最近在准备算法面试的朋友又把这题翻出来了:给定一个整数数组 nums 和一个目标值 K,统计出数组里有多少个连续子数组的和恰好等于 K。别小看这句话,它就是 LeetCode 第 560 题,也是“前缀和 + 哈希表”这个套路里最经典的入门题。我记得自己第一次被问到的时候,第一反应是暴力枚举,两层循环先把所有区间和算出来再说;代码能跑,面试官紧接着一句“数组长度十万你怎么办”,我就知道自己想浅了。这篇文章不会只给一段标准答案,我想把一条完整的思考链讲出来:为什么暴力不可取、前缀和是怎么把区间和变成一次减法的、哈希表又是怎么把复杂度压到 O(n) 的,顺带把实际调试中容易踩的坑都点一遍。不管你是刚开始刷题的新手,还是准备面试前想快速整理套路,这篇都可以当作一次完整的思路复盘。
1. 题目拆解:先确认“子数组”和“和等于 K”到底在问什么
1.1 约定一个例子,后面全靠它说话
先拿最简单的场景举例:nums = [1, 2, 3],K = 3。符合条件的连续子数组有两段:
- 第一段是
nums[0..1],也就是[1, 2],元素和是 3; - 第二段是
nums[2..2],也就是只包含最后一个元素[3],单个元素的和也是 3。
所以答案应该是 2。这里有几个容易模糊的概念,我建议写代码前先在心里过一遍:
- “子数组”要求连续,必须是从原数组中截出来的一段,不能跳着选元素;
- 单个元素本身就可以构成一个长度为一的子数组,题目没有长度下限;
- 我们要统计的是“一共有多少个这样的区间”,不是返回区间的下标,也不是问“是否存在一个”;
- 空子数组一般不参与计数,后续代码里也要避免不小心把空区间算进去。
把这些边界想清楚,后面写代码时才不会在细节上反复纠结。
1.2 这题为什么值得单独拆开讲
从表面看,这只是一个数组求和题,但它背后串联起来的基础工具很多:区间和的计算方式、空间换时间的优化思路、还有对负数元素如何处理。很多人一开始只用两层循环累加,觉得“能跑就行”,但一旦数据规模上来就原形毕露。
更重要的是,“统计连续区间和等于某个数”这个模型在工作中非常常见。举个实际例子:你手头有某商品一年内每天的销量,想统计有多少个连续时间段的总销量正好等于一个库存阈值。数据量小的时候,Excel 拉一下能对付;数据量一大,就必须用算法思路来解决。也就是说,这题不只是在面试里出现,它本质上就是“连续区间统计”这一类问题的代表。
如果你顺着这一篇把思路搞明白,后面遇到“和能被 K 整除的子数组”“二维矩阵里和为 K 的子矩阵”这些变体,也能很快迁移过去。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 暴力解法先把问题跑通:从 O(n^3) 到 O(n^2)
2.1 最笨的办法:三重循环枚举所有区间
新手拿到题,第一反应一定是把所有可能的子数组都列出来,逐个算和。一个区间由起点和终点决定,所以可以先枚举起点 i,再枚举终点 j,然后从 i 到 j 做一次累加。写成代码是这个样子:
python复制def subarray_sum_brute(nums, k):
n = len(nums)
res = 0
for i in range(n):
for j in range(i, n):
total = 0
for m in range(i, j + 1):
total += nums[m]
if total == k:
res += 1
return res
这个版本的时间复杂度是 O(n^3)。为什么是
