Skip to content

Commit 2a91086

Browse files
committed
feat: add solutions to lc problems: No.0523,0525
* No.0523.Continuous Subarray Sum * No.0525.Contiguous Array
1 parent 1f45187 commit 2a91086

File tree

17 files changed

+466
-146
lines changed

17 files changed

+466
-146
lines changed

lcof2/剑指 Offer II 011. 0 和 1 个数相同的子数组/README.md

+52-48
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,15 @@
3939

4040
<!-- 这里可写通用的实现逻辑 -->
4141

42-
前缀和加哈希表,把 0 当作 -1 处理,题目变成求和为 0 的子数组
42+
前缀和 + 哈希表,把 0 当作 -1 处理,题目变成求和为 0 的子数组。
43+
44+
遍历数组,用哈希表 mp 记录某个前缀和第一次出现的位置。初始值 `mp[0] = -1`
45+
46+
当前缀和 s 在此前出现过,说明这两个前缀和区间差构成的所有元素和为 0,满足条件,更新 ans 值。否则将 s 记录到 mp 中。
47+
48+
最后返回 ans。
49+
50+
> 这里初始化 `mp[0] = -1`,是为了统一操作。当数组从第一个元素开始的前 n 个元素的和为 0 时,也可以用 `ans = max(ans, i - mp[s])`
4351
4452
<!-- tabs:start -->
4553

@@ -50,14 +58,14 @@
5058
```python
5159
class Solution:
5260
def findMaxLength(self, nums: List[int]) -> int:
53-
m = {0: -1}
54-
ans, sum = 0, 0
55-
for i, num in enumerate(nums):
56-
sum += 1 if num == 1 else -1
57-
if sum in m:
58-
ans = max(ans, i - m[sum])
61+
s = ans = 0
62+
mp = {0: -1}
63+
for i, v in enumerate(nums):
64+
s += 1 if v == 1 else -1
65+
if s in mp:
66+
ans = max(ans, i - mp[s])
5967
else:
60-
m[sum] = i
68+
mp[s] = i
6169
return ans
6270
```
6371

@@ -68,38 +76,57 @@ class Solution:
6876
```java
6977
class Solution {
7078
public int findMaxLength(int[] nums) {
71-
Map<Integer, Integer> m = new HashMap<>();
72-
m.put(0, -1);
73-
int ans = 0, sum = 0;
74-
for (int i = 0; i < nums.length; i++) {
75-
sum += nums[i] == 1 ? 1 : -1;
76-
if (m.containsKey(sum)) {
77-
ans = Math.max(ans, i - m.get(sum));
79+
Map<Integer, Integer> mp = new HashMap<>();
80+
mp.put(0, -1);
81+
int s = 0, ans = 0;
82+
for (int i = 0; i < nums.length; ++i) {
83+
s += nums[i] == 1 ? 1 : -1;
84+
if (mp.containsKey(s)) {
85+
ans = Math.max(ans, i - mp.get(s));
7886
} else {
79-
m.put(sum, i);
87+
mp.put(s, i);
8088
}
8189
}
8290
return ans;
8391
}
8492
}
8593
```
8694

95+
### **C++**
96+
97+
```cpp
98+
class Solution {
99+
public:
100+
int findMaxLength(vector<int>& nums) {
101+
unordered_map<int, int> mp;
102+
int s = 0, ans = 0;
103+
mp[0] = -1;
104+
for (int i = 0; i < nums.size(); ++i)
105+
{
106+
s += nums[i] == 1 ? 1 : -1;
107+
if (mp.count(s)) ans = max(ans, i - mp[s]);
108+
else mp[s] = i;
109+
}
110+
return ans;
111+
}
112+
};
113+
```
114+
87115
### **Go**
88116
89117
```go
90118
func findMaxLength(nums []int) int {
91-
m := map[int]int{0: -1}
92-
ans, sum := 0, 0
93-
for i, num := range nums {
94-
if num == 0 {
95-
sum -= 1
96-
} else {
97-
sum += 1
119+
mp := map[int]int{0: -1}
120+
s, ans := 0, 0
121+
for i, v := range nums {
122+
if v == 0 {
123+
v = -1
98124
}
99-
if j, ok := m[sum]; ok {
125+
s += v
126+
if j, ok := mp[s]; ok {
100127
ans = max(ans, i-j)
101128
} else {
102-
m[sum] = i
129+
mp[s] = i
103130
}
104131
}
105132
return ans
@@ -113,29 +140,6 @@ func max(a, b int) int {
113140
}
114141
```
115142

116-
### **C++**
117-
118-
```cpp
119-
class Solution {
120-
public:
121-
int findMaxLength(vector<int>& nums) {
122-
int presum = 0;
123-
int maxlen = 0;
124-
unordered_map<int, int> mp;
125-
mp[0] = -1;
126-
for (int i = 0; i < nums.size(); i++) {
127-
presum += nums[i] == 0? -1: 1;
128-
if (mp.find(presum) != mp.end())
129-
maxlen = max(maxlen, i - mp[presum]);
130-
else
131-
mp[presum] = i;
132-
}
133-
134-
return maxlen;
135-
}
136-
};
137-
```
138-
139143
### **...**
140144

141145
```
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
class Solution {
22
public:
33
int findMaxLength(vector<int>& nums) {
4-
int presum = 0;
5-
int maxlen = 0;
64
unordered_map<int, int> mp;
5+
int s = 0, ans = 0;
76
mp[0] = -1;
8-
for (int i = 0; i < nums.size(); i++) {
9-
presum += nums[i] == 0? -1: 1;
10-
if (mp.find(presum) != mp.end())
11-
maxlen = max(maxlen, i - mp[presum]);
12-
else
13-
mp[presum] = i;
7+
for (int i = 0; i < nums.size(); ++i)
8+
{
9+
s += nums[i] == 1 ? 1 : -1;
10+
if (mp.count(s)) ans = max(ans, i - mp[s]);
11+
else mp[s] = i;
1412
}
15-
16-
return maxlen;
13+
return ans;
1714
}
1815
};
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
func findMaxLength(nums []int) int {
2-
m := map[int]int{0: -1}
3-
ans, sum := 0, 0
4-
for i, num := range nums {
5-
if num == 0 {
6-
sum -= 1
7-
} else {
8-
sum += 1
2+
mp := map[int]int{0: -1}
3+
s, ans := 0, 0
4+
for i, v := range nums {
5+
if v == 0 {
6+
v = -1
97
}
10-
if j, ok := m[sum]; ok {
8+
s += v
9+
if j, ok := mp[s]; ok {
1110
ans = max(ans, i-j)
1211
} else {
13-
m[sum] = i
12+
mp[s] = i
1413
}
1514
}
1615
return ans
@@ -21,4 +20,4 @@ func max(a, b int) int {
2120
return a
2221
}
2322
return b
24-
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
class Solution {
22
public int findMaxLength(int[] nums) {
3-
Map<Integer, Integer> m = new HashMap<>();
4-
m.put(0, -1);
5-
int ans = 0, sum = 0;
6-
for (int i = 0; i < nums.length; i++) {
7-
sum += nums[i] == 1 ? 1 : -1;
8-
if (m.containsKey(sum)) {
9-
ans = Math.max(ans, i - m.get(sum));
3+
Map<Integer, Integer> mp = new HashMap<>();
4+
mp.put(0, -1);
5+
int s = 0, ans = 0;
6+
for (int i = 0; i < nums.length; ++i) {
7+
s += nums[i] == 1 ? 1 : -1;
8+
if (mp.containsKey(s)) {
9+
ans = Math.max(ans, i - mp.get(s));
1010
} else {
11-
m.put(sum, i);
11+
mp.put(s, i);
1212
}
1313
}
1414
return ans;
1515
}
16-
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
class Solution:
22
def findMaxLength(self, nums: List[int]) -> int:
3-
m = {0: -1}
4-
ans, sum = 0, 0
5-
for i, num in enumerate(nums):
6-
sum += 1 if num == 1 else -1
7-
if sum in m:
8-
ans = max(ans, i - m[sum])
3+
s = ans = 0
4+
mp = {0: -1}
5+
for i, v in enumerate(nums):
6+
s += 1 if v == 1 else -1
7+
if s in mp:
8+
ans = max(ans, i - mp[s])
99
else:
10-
m[sum] = i
10+
mp[s] = i
1111
return ans

solution/0500-0599/0523.Continuous Subarray Sum/README.md

+74-1
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,95 @@
3939

4040
<!-- 这里可写通用的实现逻辑 -->
4141

42+
前缀和 + 哈希表。
43+
44+
要满足区间和是 k 的倍数,也即 `s[i] - s[j] = n * k` (其中 `i - j >= 2`),变形,得 `s[i] / k - s[j] / k = n`,所以只要满足 `s[i] % k == s[j] % k` 即可。
45+
4246
<!-- tabs:start -->
4347

4448
### **Python3**
4549

4650
<!-- 这里可写当前语言的特殊实现逻辑 -->
4751

4852
```python
49-
53+
class Solution:
54+
def checkSubarraySum(self, nums: List[int], k: int) -> bool:
55+
s = 0
56+
mp = {0: -1}
57+
for i, v in enumerate(nums):
58+
s += v
59+
r = s % k
60+
if r in mp and i - mp[r] >= 2:
61+
return True
62+
if r not in mp:
63+
mp[r] = i
64+
return False
5065
```
5166

5267
### **Java**
5368

5469
<!-- 这里可写当前语言的特殊实现逻辑 -->
5570

5671
```java
72+
class Solution {
73+
public boolean checkSubarraySum(int[] nums, int k) {
74+
Map<Integer, Integer> mp = new HashMap<>();
75+
mp.put(0, -1);
76+
int s = 0;
77+
for (int i = 0; i < nums.length; ++i) {
78+
s += nums[i];
79+
int r = s % k;
80+
if (mp.containsKey(r) && i - mp.get(r) >= 2) {
81+
return true;
82+
}
83+
if (!mp.containsKey(r)) {
84+
mp.put(r, i);
85+
}
86+
}
87+
return false;
88+
}
89+
}
90+
```
91+
92+
### **C++**
93+
94+
```cpp
95+
class Solution {
96+
public:
97+
bool checkSubarraySum(vector<int>& nums, int k) {
98+
unordered_map<int, int> mp;
99+
mp[0] = -1;
100+
int s = 0;
101+
for (int i = 0; i < nums.size(); ++i)
102+
{
103+
s += nums[i];
104+
int r = s % k;
105+
if (mp.count(r) && i - mp[r] >= 2) return true;
106+
if (!mp.count(r)) mp[r] = i;
107+
}
108+
return false;
109+
}
110+
};
111+
```
57112
113+
### **Go**
114+
115+
```go
116+
func checkSubarraySum(nums []int, k int) bool {
117+
mp := map[int]int{0: -1}
118+
s := 0
119+
for i, v := range nums {
120+
s += v
121+
r := s % k
122+
if j, ok := mp[r]; ok && i-j >= 2 {
123+
return true
124+
}
125+
if _, ok := mp[r]; !ok {
126+
mp[r] = i
127+
}
128+
}
129+
return false
130+
}
58131
```
59132

60133
### **...**

0 commit comments

Comments
 (0)