和为 K 的子数组
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 48 ms, 内存: 18.7 MB
/*
* 思路:
* 虽然Java Stream不适合处理这种涉及前缀和和哈希表的复杂逻辑,
* 但我们可以通过转换Stream来实现主要逻辑。
*/
import java.util.HashMap;
import java.util.stream.IntStream;
public class SubarraySumEqualsKStream {
public int subarraySum(int[] nums, int k) {
HashMap<Integer, Integer> prefixSumCount = new HashMap<>();
prefixSumCount.put(0, 1); // 初始前缀和为0,出现一次
int[] sum = {0};
int[] count = {0};
IntStream.of(nums).forEach(num -> {
sum[0] += num;
if (prefixSumCount.containsKey(sum[0] - k)) {
count[0] += prefixSumCount.get(sum[0] - k);
}
prefixSumCount.put(sum[0], prefixSumCount.getOrDefault(sum[0], 0) + 1);
});
return count[0];
}
}
解释
方法:
本题解使用了前缀和与哈希表的组合策略。首先,定义一个变量 `cur_sum` 来存储从数组开始到当前元素的连续子数组的和。使用一个哈希表 `pre_dict` 来记录所有可能的前缀和的出现次数,其中键是前缀和,值是该前缀和出现的次数。在遍历数组的每个元素时,更新 `cur_sum`。接下来,检查 `cur_sum - k` 是否存在于 `pre_dict` 中,如果存在,表示找到了一个和为 `k` 的子数组,其次数为 `pre_dict[cur_sum - k]`。然后,更新哈希表,增加当前 `cur_sum` 的计数。这种方法能够有效地在一次遍历中计算出和为 `k` 的子数组的数量。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在题解中,为什么要使用前缀和而不是直接遍历数组计算子数组的和?
▷🦆
哈希表 `pre_dict` 初始时为什么要设置 `{0: 1}`,这代表了什么意义?
▷🦆
在更新哈希表时,为什么要检查 `cur_sum - k` 而不是其他值?这与前缀和的计算有何关联?
▷