leetcode-序列和为K的数量-对前缀和和哈希代码的分析
Posted lyz_fish
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode-序列和为K的数量-对前缀和和哈希代码的分析相关的知识,希望对你有一定的参考价值。
本题与主站 560 题相同: https://leetcode.cn/problems/subarray-sum-equals-k/ 代码不是自己code出来的,对大佬写的算法的总结:
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
d = defaultdict(int, 0: 1)
ans, sum = 0, 0
for num in nums:
sum += num
ans += d[sum - k]
d[sum] += 1
return ans
其实本题的思路就是,当循环遍历到
n
u
m
s
[
i
]
nums[i]
nums[i]的时候。查看前面是否存在和为
k
−
n
u
m
s
[
i
]
k-nums[i]
k−nums[i]的前缀,我们可以称之为
n
u
m
s
[
j
]
,
j
∈
1
,
2
,
.
.
.
,
i
nums[j], j \\in \\1,2,...,i\\
nums[j],j∈1,2,...,i。
如果可以找到
∑
x
=
j
i
n
u
m
s
[
x
]
+
n
u
m
s
[
i
]
=
k
\\sum_x=j^inums[x] + nums[i] = k
∑x=jinums[x]+nums[i]=k就代表索引
j
j
j到
i
i
i之和满足k这个要求。
s
u
m
[
i
]
sum[i]
sum[i]表示前i项的和,通过变形,可以推出,
s
u
m
[
i
]
=
s
u
m
[
i
−
1
]
+
n
u
m
s
[
i
]
sum[i] = sum[i-1] + nums[i]
sum[i]=sum[i−1]+nums[i]。
而
s
u
m
[
i
]
−
k
=
s
u
m
[
i
−
1
]
+
n
u
m
s
[
i
]
−
k
sum[i] - k = sum[i-1] + nums[i] -k
sum[i]−k=sum[i−1]+nums[i]−k
初始化一个哈希表,记录所有前
i
i
i项的和的字典,形如:hashmap = 0:1,
∑
i
=
0
1
n
u
m
[
i
]
\\sum_i=0^1num[i]
∑i=01num[i]:?,
∑
i
=
0
2
n
u
m
[
i
]
\\sum_i=0^2num[i]
∑i=02num[i]:?,…,
∑
i
=
0
i
−
1
n
u
m
[
i
]
\\sum_i=0^i-1num[i]
∑i=0i−1num[i]:?。
那么如果字典中存在值为:
s
u
m
[
i
−
1
]
+
n
u
m
s
[
i
]
−
k
sum[i-1] + nums[i] - k
sum[i−1]+nums[i]−k的键,使得键
∑
i
=
0
?
n
u
m
s
[
i
]
\\sum_i=0^?nums[i]
∑i=0?nums[i] =
s
u
m
[
i
−
1
]
+
n
u
m
s
[
i
]
−
k
sum[i-1] + nums[i] - k
sum[i−1]+nums[i]−k。通过移项,就是
k
=
s
u
m
[
i
−
1
]
+
n
u
m
s
[
i
]
−
∑
i
=
0
?
n
u
m
s
[
i
]
k = sum[i-1] + nums[i] -\\sum_i=0^?nums[i]
k=sum[i−1]+nums[i]−∑i=0?nums[i],意义上,就是在
∑
i
=
?
i
n
u
m
s
[
i
]
=
k
\\sum_i=?^inums[i] = k
∑i=?inums[i]=k确实是连续子空间。
哈希表中,键为前n项的和,值为对应的前n项的和出现的次数。
只要满足条件,就在哈希表中取值,累加到result中。
以上是关于leetcode-序列和为K的数量-对前缀和和哈希代码的分析的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 560 和为K的子数组[哈希表 前缀和] HERODING的LeetCode之路
[M前缀和] lc560. 和为K的子数组(经典好题+哈希优化)