本题与主站 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}^{i}nums[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-1}num[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=?}^{i}nums[i] = k
∑i=?inums[i]=k确实是连续子空间。
哈希表中,键为前n项的和,值为对应的前n项的和出现的次数。
只要满足条件,就在哈希表中取值,累加到result中。