1
1
## 题目地址
2
+
2
3
https://leetcode.com/problems/subarray-sum-equals-k/description/
3
4
4
5
## 题目描述
6
+
5
7
```
6
8
Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.
7
9
@@ -13,31 +15,60 @@ The length of the array is in range [1, 20,000].
13
15
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].
14
16
15
17
```
18
+
16
19
## 思路
17
- 符合直觉的做法是暴力求解所有的子数组,然后分别计算和,如果等于k,count就+1.这种做法的时间复杂度为O(n^2).
18
20
19
- 这里有一种更加巧妙的方法,我们可以借助额外的空间,使用hashmap来简化时间复杂度,这种算法的时间复杂度可以达到O(n).
21
+ 符合直觉的做法是暴力求解所有的子数组,然后分别计算和,如果等于 k,count 就+1.这种做法的时间复杂度为 O(n^2),代码如下:
22
+
23
+ ``` python
24
+ class Solution :
25
+ def subarraySum (self , nums : List[int ], k : int ) -> int :
26
+ cnt, n = 0 , len (nums)
27
+ for i in range (n):
28
+ for j in range (i, n):
29
+ if (sum (nums[i:j + 1 ]) == k): cnt += 1
30
+ return cnt
31
+ ```
32
+
33
+ 实际上刚开始看到这题目的时候,我想“是否可以用滑动窗口解决?”。但是很快我就放弃了,因为看了下数组中项的取值范围有负数,这样我们扩张或者收缩窗口就比较复杂。第二个想法是前缀和,保存一个数组的前缀和,然后利用差分法得出任意区间段的和,这种想法是可行的,代码如下:
34
+
35
+ ``` python
36
+ class Solution :
37
+ def subarraySum (self , nums : List[int ], k : int ) -> int :
38
+ cnt, n = 0 , len (nums)
39
+ pre = [0 ] * (n + 1 )
40
+ for i in range (1 , n + 1 ):
41
+ pre[i] = pre[i - 1 ] + nums[i - 1 ]
42
+ for i in range (1 , n + 1 ):
43
+ for j in range (i, n + 1 ):
44
+ if (pre[j] - pre[i - 1 ] == k): cnt += 1
45
+ return cnt
46
+ ```
47
+
48
+ 这里有一种更加巧妙的方法,可以不使用前缀和数组,而是使用 hashmap 来简化时间复杂度,这种算法的时间复杂度可以达到 O(n).
49
+
50
+ 具体算法:
20
51
21
- 我们维护一个hashmap,hashmap的key为累加值acc,value为累加值acc出现的次数。
22
- 我们迭代数组,然后不断更新acc和hashmap,如果acc 等于k,那么很明显应该+1. 如果hashmap[ acc - k] 存在,
23
- 我们就把它加到结果中去即可。
52
+ - 维护一个 hashmap,hashmap 的 key 为累加值 acc,value 为累加值 acc 出现的次数。
53
+ - 迭代数组,然后不断更新 acc 和 hashmap,如果 acc 等于 k,那么很明显应该+1. 如果 hashmap[ acc - k] 存在,我们就把它加到结果中去即可。
24
54
25
- 语言比较难以解释,我画了一个图来演示nums = [ 1,2,3,3,0,3,4,2] , k = 6的情况 。
55
+ 语言比较难以解释,我画了一个图来演示 nums = [ 1,2,3,3,0,3,4,2] , k = 6 的情况 。
26
56
27
57
![ 560.subarray-sum-equals-k] ( ../assets/problems/560.subarray-sum-equals-k.jpg )
28
58
29
- 如图,当访问到nums [ 3] 的时候,hashmap如图所示,这个时候count为2 .
59
+ 如图,当访问到 nums [ 3] 的时候,hashmap 如图所示,这个时候 count 为 2 .
30
60
其中之一是[ 1,2,3] ,这个好理解。还有一个是[ 3,3] .
31
61
32
- 这个[ 3,3] 正是我们通过hashmap [ acc - k] 即hashmap [ 9 - 6] 得到的。
62
+ 这个[ 3,3] 正是我们通过 hashmap [ acc - k] 即 hashmap [ 9 - 6] 得到的。
33
63
34
64
## 关键点解析
35
65
36
- - 可以利用hashmap记录和的累加值来避免重复计算
66
+ - 前缀和
67
+ - 可以利用 hashmap 记录和的累加值来避免重复计算
37
68
38
69
## 代码
39
70
40
- * 语言支持:JS, Python
71
+ - 语言支持:JS, Python
41
72
42
73
Javascript Code:
43
74
@@ -52,7 +83,7 @@ Javascript Code:
52
83
* @param {number} k
53
84
* @return {number}
54
85
*/
55
- var subarraySum = function (nums , k ) {
86
+ var subarraySum = function (nums , k ) {
56
87
const hashmap = {};
57
88
let acc = 0 ;
58
89
let count = 0 ;
0 commit comments