Skip to content

Commit 0968be1

Browse files
committed
feat: add solutions to lc problem: No.0974
No.0974.Subarray Sums Divisible by K
1 parent b33a20e commit 0968be1

File tree

6 files changed

+87
-92
lines changed

6 files changed

+87
-92
lines changed

solution/0900-0999/0974.Subarray Sums Divisible by K/README.md

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,19 @@
4343

4444
<!-- 这里可写通用的实现逻辑 -->
4545

46-
前缀和 + 哈希表。
46+
**方法一:哈希表 + 前缀和**
4747

48-
注意:不同的语言负数取模的值不一定相同,有的语言为负数,对于这种情况需要特殊处理。
48+
假设存在 $i \leq j$,使得 $nums[i,..j]$ 的和能被 $k$ 整除,如果我们令 $s_i$ 表示 $nums[0,..i]$ 的和,令 $s_j$ 表示 $nums[0,..j]$ 的和,那么 $s_j - s_i$ 能被 $k$ 整除,即 $(s_j - s_i) \bmod k = 0$,也即 $s_j \bmod k = s_i \bmod k$。因此,我们可以用哈希表统计前缀和模 $k$ 的值的个数,从而快速判断是否存在满足条件的子数组。
49+
50+
我们用一个哈希表 $cnt$ 统计前缀和模 $k$ 的值的个数,即 $cnt[i]$ 表示前缀和模 $k$ 的值为 $i$ 的个数。初始时 $cnt[0]=1$。用变量 $s$ 表示前缀和,初始时 $s = 0$。
51+
52+
接下来,从左到右遍历数组 $nums$,对于遍历到的每个元素 $x$,我们计算 $s = (s + x) \bmod k$,然后更新答案 $ans = ans + cnt[s]$,其中 $cnt[s]$ 表示前缀和模 $k$ 的值为 $s$ 的个数。最后我们将 $cnt[s]$ 的值加 $1$,继续遍历下一个元素。
53+
54+
最终,我们返回答案 $ans$。
55+
56+
> 注意,由于 $s$ 的值可能为负数,因此我们可以将 $s$ 模 $k$ 的结果加上 $k$,再对 $k$ 取模,以确保 $s$ 的值为非负数。
57+
58+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
4959

5060
<!-- tabs:start -->
5161

@@ -56,12 +66,12 @@
5666
```python
5767
class Solution:
5868
def subarraysDivByK(self, nums: List[int], k: int) -> int:
69+
cnt = Counter({0: 1})
5970
ans = s = 0
60-
counter = Counter({0: 1})
61-
for num in nums:
62-
s += num
63-
ans += counter[s % k]
64-
counter[s % k] += 1
71+
for x in nums:
72+
s = (s + x) % k
73+
ans += cnt[s]
74+
cnt[s] += 1
6575
return ans
6676
```
6777

@@ -72,14 +82,13 @@ class Solution:
7282
```java
7383
class Solution {
7484
public int subarraysDivByK(int[] nums, int k) {
75-
Map<Integer, Integer> counter = new HashMap<>();
76-
counter.put(0, 1);
77-
int s = 0, ans = 0;
78-
for (int num : nums) {
79-
s += num;
80-
int t = (s % k + k) % k;
81-
ans += counter.getOrDefault(t, 0);
82-
counter.put(t, counter.getOrDefault(t, 0) + 1);
85+
Map<Integer, Integer> cnt = new HashMap<>();
86+
cnt.put(0, 1);
87+
int ans = 0, s = 0;
88+
for (int x : nums) {
89+
s = ((s + x) % k + k) % k;
90+
ans += cnt.getOrDefault(s, 0);
91+
cnt.merge(s, 1, Integer::sum);
8392
}
8493
return ans;
8594
}
@@ -92,14 +101,11 @@ class Solution {
92101
class Solution {
93102
public:
94103
int subarraysDivByK(vector<int>& nums, int k) {
95-
unordered_map<int, int> counter;
96-
counter[0] = 1;
97-
int s = 0, ans = 0;
98-
for (int& num : nums) {
99-
s += num;
100-
int t = (s % k + k) % k;
101-
ans += counter[t];
102-
++counter[t];
104+
unordered_map<int, int> cnt{{0, 1}};
105+
int ans = 0, s = 0;
106+
for (int& x : nums) {
107+
s = ((s + x) % k + k) % k;
108+
ans += cnt[s]++;
103109
}
104110
return ans;
105111
}
@@ -109,16 +115,15 @@ public:
109115
### **Go**
110116
111117
```go
112-
func subarraysDivByK(nums []int, k int) int {
113-
counter := map[int]int{0: 1}
114-
ans, s := 0, 0
115-
for _, num := range nums {
116-
s += num
117-
t := (s%k + k) % k
118-
ans += counter[t]
119-
counter[t]++
118+
func subarraysDivByK(nums []int, k int) (ans int) {
119+
cnt := map[int]int{0: 1}
120+
s := 0
121+
for _, x := range nums {
122+
s = ((s+x)%k + k) % k
123+
ans += cnt[s]
124+
cnt[s]++
120125
}
121-
return ans
126+
return
122127
}
123128
```
124129

solution/0900-0999/0974.Subarray Sums Divisible by K/README_EN.md

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@
4343
```python
4444
class Solution:
4545
def subarraysDivByK(self, nums: List[int], k: int) -> int:
46+
cnt = Counter({0: 1})
4647
ans = s = 0
47-
counter = Counter({0: 1})
48-
for num in nums:
49-
s += num
50-
ans += counter[s % k]
51-
counter[s % k] += 1
48+
for x in nums:
49+
s = (s + x) % k
50+
ans += cnt[s]
51+
cnt[s] += 1
5252
return ans
5353
```
5454

@@ -57,14 +57,13 @@ class Solution:
5757
```java
5858
class Solution {
5959
public int subarraysDivByK(int[] nums, int k) {
60-
Map<Integer, Integer> counter = new HashMap<>();
61-
counter.put(0, 1);
62-
int s = 0, ans = 0;
63-
for (int num : nums) {
64-
s += num;
65-
int t = (s % k + k) % k;
66-
ans += counter.getOrDefault(t, 0);
67-
counter.put(t, counter.getOrDefault(t, 0) + 1);
60+
Map<Integer, Integer> cnt = new HashMap<>();
61+
cnt.put(0, 1);
62+
int ans = 0, s = 0;
63+
for (int x : nums) {
64+
s = ((s + x) % k + k) % k;
65+
ans += cnt.getOrDefault(s, 0);
66+
cnt.merge(s, 1, Integer::sum);
6867
}
6968
return ans;
7069
}
@@ -77,14 +76,11 @@ class Solution {
7776
class Solution {
7877
public:
7978
int subarraysDivByK(vector<int>& nums, int k) {
80-
unordered_map<int, int> counter;
81-
counter[0] = 1;
82-
int s = 0, ans = 0;
83-
for (int& num : nums) {
84-
s += num;
85-
int t = (s % k + k) % k;
86-
ans += counter[t];
87-
++counter[t];
79+
unordered_map<int, int> cnt{{0, 1}};
80+
int ans = 0, s = 0;
81+
for (int& x : nums) {
82+
s = ((s + x) % k + k) % k;
83+
ans += cnt[s]++;
8884
}
8985
return ans;
9086
}
@@ -94,16 +90,15 @@ public:
9490
### **Go**
9591
9692
```go
97-
func subarraysDivByK(nums []int, k int) int {
98-
counter := map[int]int{0: 1}
99-
ans, s := 0, 0
100-
for _, num := range nums {
101-
s += num
102-
t := (s%k + k) % k
103-
ans += counter[t]
104-
counter[t]++
93+
func subarraysDivByK(nums []int, k int) (ans int) {
94+
cnt := map[int]int{0: 1}
95+
s := 0
96+
for _, x := range nums {
97+
s = ((s+x)%k + k) % k
98+
ans += cnt[s]
99+
cnt[s]++
105100
}
106-
return ans
101+
return
107102
}
108103
```
109104

solution/0900-0999/0974.Subarray Sums Divisible by K/Solution.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
class Solution {
22
public:
33
int subarraysDivByK(vector<int>& nums, int k) {
4-
unordered_map<int, int> counter;
5-
counter[0] = 1;
6-
int s = 0, ans = 0;
7-
for (int& num : nums) {
8-
s += num;
9-
int t = (s % k + k) % k;
10-
ans += counter[t];
11-
++counter[t];
4+
unordered_map<int, int> cnt{{0, 1}};
5+
int ans = 0, s = 0;
6+
for (int& x : nums) {
7+
s = ((s + x) % k + k) % k;
8+
ans += cnt[s]++;
129
}
1310
return ans;
1411
}
Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
func subarraysDivByK(nums []int, k int) int {
2-
counter := map[int]int{0: 1}
3-
ans, s := 0, 0
4-
for _, num := range nums {
5-
s += num
6-
t := (s%k + k) % k
7-
ans += counter[t]
8-
counter[t]++
1+
func subarraysDivByK(nums []int, k int) (ans int) {
2+
cnt := map[int]int{0: 1}
3+
s := 0
4+
for _, x := range nums {
5+
s = ((s+x)%k + k) % k
6+
ans += cnt[s]
7+
cnt[s]++
98
}
10-
return ans
9+
return
1110
}

solution/0900-0999/0974.Subarray Sums Divisible by K/Solution.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
class Solution {
22
public int subarraysDivByK(int[] nums, int k) {
3-
Map<Integer, Integer> counter = new HashMap<>();
4-
counter.put(0, 1);
5-
int s = 0, ans = 0;
6-
for (int num : nums) {
7-
s += num;
8-
int t = (s % k + k) % k;
9-
ans += counter.getOrDefault(t, 0);
10-
counter.put(t, counter.getOrDefault(t, 0) + 1);
3+
Map<Integer, Integer> cnt = new HashMap<>();
4+
cnt.put(0, 1);
5+
int ans = 0, s = 0;
6+
for (int x : nums) {
7+
s = ((s + x) % k + k) % k;
8+
ans += cnt.getOrDefault(s, 0);
9+
cnt.merge(s, 1, Integer::sum);
1110
}
1211
return ans;
1312
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
class Solution:
22
def subarraysDivByK(self, nums: List[int], k: int) -> int:
3+
cnt = Counter({0: 1})
34
ans = s = 0
4-
counter = Counter({0: 1})
5-
for num in nums:
6-
s += num
7-
ans += counter[s % k]
8-
counter[s % k] += 1
5+
for x in nums:
6+
s = (s + x) % k
7+
ans += cnt[s]
8+
cnt[s] += 1
99
return ans

0 commit comments

Comments
 (0)