法算day10

法算day10
lief
[up主专用,视频内嵌代码贴在这]
和为k的子数组
问题描述
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例 1:
输入:nums = [1,1,1], k = 2
输出:2示例 2:
输入:nums = [1,2,3], k = 3
输出:2
提示:
1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107
算法思路
这个问题的关键在于理解前缀和的概念:
- 前缀和是指从数组起始位置到当前位置的所有元素之和
- 如果从位置 i 到位置 j 的子数组和为 k,那么
prefix_sum[j] - prefix_sum[i-1] = k - 可以转化为
prefix_sum[j] - k = prefix_sum[i-1]
python版(前缀和+哈希表)
1 | def subarraySum(nums, k): |
✅ 说明:
- 时间复杂度: O(n),只需要遍历数组一次
- 空间复杂度: O(n),最坏情况下需要存储n个不同的前缀和
疑点:为什么需要初始化 {0: 1}
初始化 prefix_sum_count = {0: 1} 是为了处理从数组开头开始的子数组:
- 当子数组从索引0开始时,prefix_sum[i-1] 实际上不存在
- 我们可以将其视为前缀和为0,出现在索引-1位置
- 这样就能统一处理所有情况
示例说明:nums3 = [1, 3, 2, 4, 5, 6], k3 = 6
- 初始状态
1
2
3
4
5nums = [1, 3, 2, 4, 5, 6]
k = 6
prefix_sum_count = {0: 1} # 初始前缀和字典,0出现1次
current_sum = 0
count = 0 - 第1次循环 (i=0, num=1)
1
2
3
4
5
6
7
8当前元素: nums[0] = 1
更新当前前缀和: current_sum = 0 + 1 = 1
检查是否存在 current_sum - k = 1 - 6 = -5 在 prefix_sum_count 中
- -5 不在字典中,所以 count 不变 (count=0)
更新前缀和字典: prefix_sum_count[1] = 1
现在 prefix_sum_count = {0: 1, 1: 1} - 第2次循环 (i=1, num=3)-第3次循环 (i=2, num=2)
1
2
3
4
5
6
7
8当前元素: nums[1] = 3
更新当前前缀和: current_sum = 1 + 3 = 4
检查是否存在 current_sum - k = 4 - 6 = -2 在 prefix_sum_count 中
- -2 不在字典中,所以 count 不变 (count=0)
更新前缀和字典: prefix_sum_count[4] = 1
现在 prefix_sum_count = {0: 1, 1: 1, 4: 1}1
2
3
4
5
6
7
8
9当前元素: nums[2] = 2
更新当前前缀和: current_sum = 4 + 2 = 6
检查是否存在 current_sum - k = 6 - 6 = 0 在 prefix_sum_count 中
- 0 在字典中,出现次数为1
- 所以 count += 1 → count = 1
更新前缀和字典: prefix_sum_count[6] = 1
现在 prefix_sum_count = {0: 1, 1: 1, 4: 1, 6: 1} - 第4次循环 (i=3, num=4)
1
2
3
4
5
6
7
8
9当前元素: nums[3] = 4
更新当前前缀和: current_sum = 6 + 4 = 10
检查是否存在 current_sum - k = 10 - 6 = 4 在 prefix_sum_count 中
- 4 在字典中,出现次数为1
- 所以 count += 1 → count = 2
更新前缀和字典: prefix_sum_count[10] = 1
现在 prefix_sum_count = {0: 1, 1: 1, 4: 1, 6: 1, 10: 1} - 第5次循环 (i=4, num=5)
1
2
3
4
5
6
7
8当前元素: nums[4] = 5
更新当前前缀和: current_sum = 10 + 5 = 15
检查是否存在 current_sum - k = 15 - 6 = 9 在 prefix_sum_count 中
- 9 不在字典中,所以 count 不变 (count=2)
更新前缀和字典: prefix_sum_count[15] = 1
现在 prefix_sum_count = {0: 1, 1: 1, 4: 1, 6: 1, 10: 1, 15: 1} - 第6次循环 (i=5, num=6)
1
2
3
4
5
6
7
8
9当前元素: nums[5] = 6
更新当前前缀和: current_sum = 15 + 6 = 21
检查是否存在 current_sum - k = 21 - 6 = 15 在 prefix_sum_count 中
- 15 在字典中,出现次数为1
- 所以 count += 1 → count = 3
更新前缀和字典: prefix_sum_count[21] = 1
现在 prefix_sum_count = {0: 1, 1: 1, 4: 1, 6: 1, 10: 1, 15: 1, 21: 1}
java版
1 | import java.util.HashMap; |
Comment
匿名评论隐私政策









