前缀和
碰到了一道题,用到了前缀和,记录一下
给你一个整数数组
nums
和一个整数k
,请你统计并返回 该数组中和为k
的子数组的个数 。子数组是数组中元素的连续非空序列。
示例 1:
1
2 输入:nums = [1,1,1], k = 2
输出:2示例 2:
1
2 输入:nums = [1,2,3], k = 3
输出:2
我的超级烂写法(AC):
1 | func subarraySum(nums []int, k int) int { |
- 前缀树
请务必记住下面这个定义:
我们使用一个叫做“前缀和”的概念。对于数组中的任何位置 j,前缀和 pre[j] 是数组中从第一个元素到第 j 个元素的总和。这意味着如果你想知道从元素 i+1 到 j 的子数组的和,你可以用 pre[j] - pre[i] 来计算。
因此,在我的代码上改成前缀树版本的,根本不行,所以我的一开始的思路就是错的
1 | func subarraySum(nums []int, k int) int { |
把里面一层的遍历改成 从尾巴到头部 遍历的一个方式
这样子可以实现前缀树的性质:从第一个到第i个的和
所以我们可以使用 哈希表 + 前缀树 来优化他
map[int]int{num,count}
来表示连续和的出现的次数
然后我们使用 preSum - k
来表示
1 | func subarraySum(nums []int, k int) int { |
preSum
记录的是从头到第i个的和pre , ok := preArr[preSum - k]
这个就表示arr[j] - arr[i] = arr[ i+1 ~j ]
的连续和,那么反观我们写的算式:preSum = arr[j]
k=arr[i]
那么pre 的存在个数就是 连续个数,非常巧妙
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Echin の 博客!