LeetCode Hot100题目解析:和为K的子数组数量
技术点:哈希表、前缀和
本期我们讲解LeetCode Hot100中的一道经典题目——和为K的子数组数量(Subarray Sum Equals K)。这道题考查哈希表与前缀和的结合应用,非常适合初学者理解数组与哈希思想。
题目描述
给定一个整数数组 nums
和一个整数 k
,请你统计并返回该数组中和为 k
的连续子数组的个数。
示例:
输入: nums = [1,1,1], k = 2
输出: 2
解释: 子数组 [1,1] 有2个。
解题思路
-
核心思想:前缀和 + 哈希表
- 用前缀和表示从数组开头到当前位置的所有元素和。
- 如果前缀和为
sum
,想找出某段区间的和为k
,只需判断之前是否有前缀和为sum-k
。 - 用哈希表(HashMap)记录每个前缀和出现的次数。
-
具体步骤
- 初始化前缀和
sum = 0
,计数器count = 0
。 - 初始化一个哈希表,存储前缀和出现的次数,最开始
map.put(0,1)
(表示前缀和为0出现1次)。 - 遍历数组,累计前缀和sum。
- 每一步判断
sum - k
是否在哈希表中,如果在,说明找到了一个或多个区间和为k。 - 更新哈希表中当前前缀和的次数。
- 初始化前缀和
-
时间复杂度分析
- 整体只需遍历一遍数组,时间复杂度O(n)。
Java完整解题代码(详细注释)
import java.util.HashMap;
public class Solution {
/**
* 统计和为k的连续子数组数量
* @param nums 输入数组
* @param k 目标和
* @return 子数组数量
*/
public int subarraySum(int[] nums, int k) {
// 哈希表,key为前缀和,value为前缀和出现的次数
HashMap<Integer, Integer> map = new HashMap<>();
// 初始化,前缀和为0出现1次
map.put(0, 1);
int sum = 0;
int count = 0;
for (int num : nums) {
sum += num; // 计算当前前缀和
// 若sum - k在map中,表示存在前缀和区间和为k
if (map.containsKey(sum - k)) {
count += map.get(sum - k);
}
// 更新当前前缀和出现次数
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
return count;
}
}
总结
- 本题利用前缀和与哈希表,巧妙实现O(n)的高效解法。
- 适合初学者理解连续区间和与哈希统计思想。
希望这篇讲解能帮你彻底搞懂这道高频面试题!
文章标签: LeetCode,算法,Java,哈希表,前缀和,数组,面试