
2026-03-26:统计主要元素子数组数目Ⅰ。用go语言,给定一个整数数组 nums 和一个整数 target。
你要统计数组中连续且非空的所有子数组中,满足如下条件的子数组数量:在该子数组里,target 这个数出现的次数严格大于子数组长度的一半。
也就是说,若子数组长度为 len,target 在其中出现了 cnt 次,则必须满足 cnt > len/2。
返回满足条件的子数组总数。
1 <= nums.length <= 1000。
1 <= nums[i] <= 1000000000。
1 <= target <= 1000000000。
输入: nums = [1,2,2,3], target = 2。
输出: 5。
解释:
以 target = 2 为主要元素的子数组有:
nums[1..1] = [2]
nums[2..2] = [2]
nums[1..2] = [2,2]
nums[0..2] = [1,2,2]
nums[1..3] = [2,2,3]
因此共有 5 个这样的子数组。
题目来自力扣3737。
我们以输入 nums = [1,2,2,3],target = 2 为例,分步骤、逐元素讲解代码的执行逻辑,全程不写代码,只讲核心思路和计算过程。
题目要求:统计所有连续非空子数组中,target 出现次数 严格大于 子数组长度一半的子数组数量。
L,target 出现次数为 c,满足 c > L/2 即符合条件。target 出现次数 - 非target 元素次数 > 0(推导:c > (L-c) → 2c-L >0 → c-(L-c) >0)。代码的核心思路:用前缀和 + 计数数组,快速统计满足条件的子数组数量,避免暴力枚举所有子数组。
n = 4(nums 有4个元素)。cnt:长度为 4*2+1=9,用来记录前缀和数值出现的次数,初始全为0。cnt[4] = 1(前缀和的初始基准值,对应前缀和为0)。s:当前前缀和的偏移值,初始为 4(对应前缀和0);f:记录以当前元素结尾的符合条件的子数组数量,初始为0;ans:最终总数量,初始为0。我们按顺序遍历 1 → 2 → 2 → 3 四个元素,每一步都做判断、更新变量、统计数量、更新计数数组四个操作。
x = 1(不是 target=2)s 减1 → s = 4-1 = 3;s 对应的计数数组值,减少 f → f = 0 - cnt[3] = 0-0 = 0;x = 2(是 target=2)s 对应的计数数组值,增加 f → f = 0 + cnt[3] = 0+1 = 1;s 加1 → s = 3+1 = 4;[2](下标1)。x = 2(是 target=2)s 对应的计数数组值,增加 f → f = 1 + cnt[4] = 1+2 = 3;s 加1 → s = 4+1 = 5;[2](下标2)、[2,2](下标1-2)、[1,2,2](下标0-2)。x = 3(不是 target=2)s 减1 → s = 5-1 = 4;s 对应的计数数组值,减少 f → f = 3 - cnt[4] = 3-2 = 1;[2,2,3](下标1-3)。遍历结束后,ans = 5,与题目输出完全一致。
n,因此总时间复杂度为 O(n)。cnt,长度为 2n+1,是唯一的额外空间;package main
import (
"fmt"
)
func countMajoritySubarrays(nums []int, target int) (ans int64) {
n := len(nums)
cnt := make([]int, n*2+1)
cnt[n] = 1
s, f := n, 0
for _, x := range nums {
if x == target {
f += cnt[s]
s++
} else {
s--
f -= cnt[s]
}
ans += int64(f)
cnt[s]++
}
return
}
func main() {
nums := []int{1, 2, 2, 3}
target := 2
result := countMajoritySubarrays(nums, target)
fmt.Println(result)
}

# -*-coding:utf-8-*-
defcountMajoritySubarrays(nums, target):
n = len(nums)
# 偏移量 n,避免负数下标
offset = n
cnt = [0] * (n * 2 + 1)
cnt[offset] = 1
s = offset
f = 0
ans = 0
for x in nums:
if x == target:
f += cnt[s]
s += 1
else:
s -= 1
f -= cnt[s]
ans += f
cnt[s] += 1
return ans
defmain():
nums = [1, 2, 2, 3]
target = 2
result = countMajoritySubarrays(nums, target)
print(result)
if __name__ == "__main__":
main()
#include <iostream>
#include <vector>
usingnamespace std;
long long countMajoritySubarrays(vector<int>& nums, int target) {
int n = nums.size();
vector<int> cnt(n * 2 + 1, 0);
cnt[n] = 1;
int s = n, f = 0;
longlong ans = 0;
for (int x : nums) {
if (x == target) {
f += cnt[s];
s++;
} else {
s--;
f -= cnt[s];
}
ans += f;
cnt[s]++;
}
return ans;
}
int main() {
vector<int> nums = {1, 2, 2, 3};
int target = 2;
longlong result = countMajoritySubarrays(nums, target);
cout << result << endl;
return0;
}

·
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。
·