2026-05-17:中心子数组的数量。用go语言,给定一个整数数组 nums。 考虑数组中的任意一个连续非空子数组。若该子数组
【摘要】 2026-05-17:中心子数组的数量。用go语言,给定一个整数数组 nums。考虑数组中的任意一个连续非空子数组。若该子数组的“总和”恰好等于该子数组中“至少一个元素的值”,则称这个子数组为中心子数组。你的任务是:统计 nums 中所有中心子数组的数量,并返回这个数量。1 <= nums.length <= 500。-100000 <= nums[i] <= 100000。输入: nums...
2026-05-17:中心子数组的数量。用go语言,给定一个整数数组 nums。
考虑数组中的任意一个连续非空子数组。若该子数组的“总和”恰好等于该子数组中“至少一个元素的值”,则称这个子数组为中心子数组。
你的任务是:统计 nums 中所有中心子数组的数量,并返回这个数量。
1 <= nums.length <= 500。
-100000 <= nums[i] <= 100000。
输入: nums = [-1,1,0]。
输出: 5。
解释:
所有单元素子数组([-1],[1],[0])都是中心子数组。
子数组 [1, 0] 的元素之和为 1,且 1 存在于该子数组中。
子数组 [-1, 1, 0] 的元素之和为 0,且 0 存在于该子数组中。
因此,答案是 5。
题目来自力扣3804。
中心子数组统计过程详细解析
第一步:明确所有连续非空子数组
数组长度为3,总共有 6个 连续非空子数组(所有可能的连续片段):
[-1](起始索引0,结束索引0)[-1,1](起始索引0,结束索引1)[-1,1,0](起始索引0,结束索引2)[1](起始索引1,结束索引1)[1,0](起始索引1,结束索引2)[0](起始索引2,结束索引2)
第二步:逐一枚举所有子数组,判断是否为中心子数组
代码的核心逻辑是:固定子数组的起点,依次扩展终点,遍历所有子数组,同时用哈希表记录当前子数组包含的元素,快速判断「总和是否存在于子数组中」。
阶段1:固定起点为索引0(元素:-1)
从第一个元素开始,逐步向右扩展子数组:
- 子数组 [-1]
- 元素:{-1}
- 总和:-1
- 判断:总和 -1 存在于元素中 → 是中心子数组,计数+1
- 子数组 [-1,1]
- 元素:{-1,1}
- 总和:-1+1=0
- 判断:总和0 不存在于元素中 → 不是,计数不变
- 子数组 [-1,1,0]
- 元素:{-1,1,0}
- 总和:-1+1+0=0
- 判断:总和0 存在于元素中 → 是中心子数组,计数+1
✅ 此阶段累计:2个
阶段2:固定起点为索引1(元素:1)
清空之前的记录,从第二个元素开始扩展:
- 子数组 [1]
- 元素:{1}
- 总和:1
- 判断:总和1 存在于元素中 → 是中心子数组,计数+1
- 子数组 [1,0]
- 元素:{1,0}
- 总和:1+0=1
- 判断:总和1 存在于元素中 → 是中心子数组,计数+1
✅ 此阶段累计:2个(总计数:4)
阶段3:固定起点为索引2(元素:0)
清空之前的记录,从第三个元素开始扩展:
- 子数组 [0]
- 元素:{0}
- 总和:0
- 判断:总和0 存在于元素中 → 是中心子数组,计数+1
✅ 此阶段累计:1个(总计数:5)
第三步:最终统计
所有符合条件的中心子数组:
- [-1]
- [-1,1,0]
- [1]
- [1,0]
- [0]
总计 5个,与题目输出一致。
代码核心逻辑通俗解释
- 双重循环遍历所有子数组:外层循环固定子数组的起点,内层循环从起点开始向右扩展,确定子数组的终点,覆盖所有连续子数组。
- 哈希表记录当前子数组元素:每扩展一个终点,就把新元素存入哈希表(快速去重,只记录元素是否存在)。
- 实时计算子数组总和:每扩展一个元素,就累加计算当前子数组的总和。
- 快速判断:检查「总和」是否在哈希表中(即是否存在于当前子数组),如果存在,就将结果计数+1。
时间复杂度 & 空间复杂度
1. 时间复杂度
- 外层循环:遍历数组的每个元素作为起点,执行 n 次(n是数组长度)。
- 内层循环:每个起点最多向右遍历到数组末尾,平均执行 n/2 次,总次数为 n² 级别。
- 哈希表的插入、查询操作都是 O(1) 常数时间。
- 总时间复杂度:O(n²)(n为数组长度,本题n≤500,n²=25万,完全满足要求)。
2. 空间复杂度
- 代码中使用了一个哈希表,每次遍历新起点时都会清空哈希表。
- 哈希表最多存储当前子数组的所有唯一元素,子数组最长为n,元素最多n个。
- 总空间复杂度:O(n)(额外空间仅为哈希表,最大占用n个元素的空间)。
总结
- 计算过程:通过固定起点+扩展终点遍历所有连续子数组,用哈希表记录元素,实时计算总和并判断是否符合条件;
- 时间复杂度:O(n²)(双重循环);
- 空间复杂度:O(n)(哈希表临时存储元素)。
Go完整代码如下:
package main
import (
"fmt"
)
func centeredSubarrays(nums []int) (ans int) {
has := map[int]int{}
for i := range nums {
clear(has)
s := 0
for _, x := range nums[i:] {
has[x] = 1
s += x
ans += has[s]
}
}
return
}
func main() {
nums := []int{-1, 1, 0}
result := centeredSubarrays(nums)
fmt.Println(result)
}

Python完整代码如下:
# -*-coding:utf-8-*-
def centeredSubarrays(nums):
ans = 0
n = len(nums)
for i in range(n):
has = {}
s = 0
for j in range(i, n):
x = nums[j]
has[x] = 1
s += x
ans += has.get(s, 0)
return ans
def main():
nums = [-1, 1, 0]
result = centeredSubarrays(nums)
print(result)
if __name__ == "__main__":
main()

C++完整代码如下:
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int centeredSubarrays(vector<int>& nums) {
int ans = 0;
unordered_map<int, int> has;
for (int i = 0; i < nums.size(); i++) {
has.clear();
int s = 0;
for (int j = i; j < nums.size(); j++) {
int x = nums[j];
has[x] = 1;
s += x;
ans += has[s]; // 如果 s 不存在于 map 中,has[s] 会返回 0
}
}
return ans;
}
int main() {
vector<int> nums = {-1, 1, 0};
int result = centeredSubarrays(nums);
cout << result << endl;
return 0;
}

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)