Skip to content

Commit e84ac4d

Browse files
committed
feat: add solutions to lc problem: No.1590
No.1590.Make Sum Divisible by P
1 parent 3eda552 commit e84ac4d

File tree

7 files changed

+387
-65
lines changed

7 files changed

+387
-65
lines changed

solution/1500-1599/1590.Make Sum Divisible by P/README.md

Lines changed: 140 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,53 +62,171 @@
6262

6363
<!-- 这里可写通用的实现逻辑 -->
6464

65+
**方法一:前缀和 + 哈希表**
66+
67+
我们可以先求出数组 $nums$ 所有元素之和模 $p$ 的值,记为 $k$。如果 $k$ 为 $0$,说明数组 $nums$ 所有元素之和就是 $p$ 的倍数,直接返回 $0$ 即可。
68+
69+
如果 $k$ 不为 $0$,我们需要找到一个最短的子数组,使得删除该子数组后,剩余元素之和模 $p$ 的值为 $0$。
70+
71+
我们可以遍历数组 $nums$,维护当前的前缀和模 $p$ 的值,记为 $cur$。用哈希表 $last$ 记录每个前缀和模 $p$ 的值最后一次出现的位置。
72+
73+
如果当前存在一个以 $nums[i]$ 结尾的子数组,使得删除该子数组后,剩余元素之和模 $p$ 的值为 $0$。也就是说,我们需要找到此前的一个前缀和模 $p$ 的值为 $target$ 的位置 $j$,使得 $(target + k - cur) \bmod p = 0$。那么,我们可以将 $j + 1$ 到 $i$ 这一段子数组删除,剩余元素之和模 $p$ 的值为 $0$。因此,如果存在一个 $target = (cur - k + p) \bmod p$,那么我们可以更新答案为 $\min(ans, i - j)$。接下来,我们更新 $last[cur]$ 的值为 $i$。继续遍历数组 $nums$,直到遍历结束,即可得到答案。
74+
75+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
76+
6577
<!-- tabs:start -->
6678

6779
### **Python3**
6880

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

7183
```python
72-
84+
class Solution:
85+
def minSubarray(self, nums: List[int], p: int) -> int:
86+
k = sum(nums) % p
87+
if k == 0:
88+
return 0
89+
last = {0: -1}
90+
cur = 0
91+
ans = len(nums)
92+
for i, x in enumerate(nums):
93+
cur = (cur + x) % p
94+
target = (cur - k + p) % p
95+
if target in last:
96+
ans = min(ans, i - last[target])
97+
last[cur] = i
98+
return -1 if ans == len(nums) else ans
7399
```
74100

75101
### **Java**
76102

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

79105
```java
106+
class Solution {
107+
public int minSubarray(int[] nums, int p) {
108+
int k = 0;
109+
for (int x : nums) {
110+
k = (k + x) % p;
111+
}
112+
if (k == 0) {
113+
return 0;
114+
}
115+
Map<Integer, Integer> last = new HashMap<>();
116+
last.put(0, -1);
117+
int n = nums.length;
118+
int ans = n;
119+
int cur = 0;
120+
for (int i = 0; i < n; ++i) {
121+
cur = (cur + nums[i]) % p;
122+
int target = (cur - k + p) % p;
123+
if (last.containsKey(target)) {
124+
ans = Math.min(ans, i - last.get(target));
125+
}
126+
last.put(cur, i);
127+
}
128+
return ans == n ? -1 : ans;
129+
}
130+
}
131+
```
80132

133+
### **C++**
134+
135+
```cpp
136+
class Solution {
137+
public:
138+
int minSubarray(vector<int>& nums, int p) {
139+
int k = 0;
140+
for (int& x : nums) {
141+
k = (k + x) % p;
142+
}
143+
if (k == 0) {
144+
return 0;
145+
}
146+
unordered_map<int, int> last;
147+
last[0] = -1;
148+
int n = nums.size();
149+
int ans = n;
150+
int cur = 0;
151+
for (int i = 0; i < n; ++i) {
152+
cur = (cur + nums[i]) % p;
153+
int target = (cur - k + p) % p;
154+
if (last.count(target)) {
155+
ans = min(ans, i - last[target]);
156+
}
157+
last[cur] = i;
158+
}
159+
return ans == n ? -1 : ans;
160+
}
161+
};
162+
```
163+
164+
### **Go**
165+
166+
```go
167+
func minSubarray(nums []int, p int) int {
168+
k := 0
169+
for _, x := range nums {
170+
k = (k + x) % p
171+
}
172+
if k == 0 {
173+
return 0
174+
}
175+
last := map[int]int{0: -1}
176+
n := len(nums)
177+
ans := n
178+
cur := 0
179+
for i, x := range nums {
180+
cur = (cur + x) % p
181+
target := (cur - k + p) % p
182+
if j, ok := last[target]; ok {
183+
ans = min(ans, i-j)
184+
}
185+
last[cur] = i
186+
}
187+
if ans == n {
188+
return -1
189+
}
190+
return ans
191+
}
192+
193+
func min(a, b int) int {
194+
if a < b {
195+
return a
196+
}
197+
return b
198+
}
81199
```
82200

83201
### **TypeScript**
84202

85203
```ts
86204
function minSubarray(nums: number[], p: number): number {
87-
const n = nums.length;
88-
let mod = 0;
89-
for (let i = 0; i < n; i++) {
90-
mod = (nums[i] + mod) % p;
205+
let k = 0;
206+
for (const x of nums) {
207+
k = (k + x) % p;
91208
}
92-
if (!mod) return 0;
93-
94-
let hashMap = new Map<number, number>();
95-
hashMap.set(0, -1);
209+
if (k === 0) {
210+
return 0;
211+
}
212+
const last = new Map<number, number>();
213+
last.set(0, -1);
214+
const n = nums.length;
96215
let ans = n;
97-
let subMod = 0;
98-
for (let i = 0; i < n; i++) {
99-
let cur = nums[i];
100-
subMod = (subMod + cur) % p;
101-
let target = (subMod - mod + p) % p;
102-
if (hashMap.has(target)) {
103-
let j = hashMap.get(target);
104-
ans = Math.min(i - j, ans);
105-
if (ans == 1 && ans != n) {
106-
return ans;
107-
}
216+
let cur = 0;
217+
for (let i = 0; i < n; ++i) {
218+
cur = (cur + nums[i]) % p;
219+
const target = (cur - k + p) % p;
220+
if (last.has(target)) {
221+
const j = last.get(target)!;
222+
ans = Math.min(ans, i - j);
108223
}
109-
hashMap.set(subMod, i);
224+
last.set(cur, i);
225+
}
226+
if (ans == n) {
227+
return -1;
110228
}
111-
return ans == n ? -1 : ans;
229+
return ans;
112230
}
113231
```
114232

solution/1500-1599/1590.Make Sum Divisible by P/README_EN.md

Lines changed: 128 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,44 +51,150 @@
5151
### **Python3**
5252

5353
```python
54-
54+
class Solution:
55+
def minSubarray(self, nums: List[int], p: int) -> int:
56+
k = sum(nums) % p
57+
if k == 0:
58+
return 0
59+
last = {0: -1}
60+
cur = 0
61+
ans = len(nums)
62+
for i, x in enumerate(nums):
63+
cur = (cur + x) % p
64+
target = (cur - k + p) % p
65+
if target in last:
66+
ans = min(ans, i - last[target])
67+
last[cur] = i
68+
return -1 if ans == len(nums) else ans
5569
```
5670

5771
### **Java**
5872

5973
```java
74+
class Solution {
75+
public int minSubarray(int[] nums, int p) {
76+
int k = 0;
77+
for (int x : nums) {
78+
k = (k + x) % p;
79+
}
80+
if (k == 0) {
81+
return 0;
82+
}
83+
Map<Integer, Integer> last = new HashMap<>();
84+
last.put(0, -1);
85+
int n = nums.length;
86+
int ans = n;
87+
int cur = 0;
88+
for (int i = 0; i < n; ++i) {
89+
cur = (cur + nums[i]) % p;
90+
int target = (cur - k + p) % p;
91+
if (last.containsKey(target)) {
92+
ans = Math.min(ans, i - last.get(target));
93+
}
94+
last.put(cur, i);
95+
}
96+
return ans == n ? -1 : ans;
97+
}
98+
}
99+
```
100+
101+
### **C++**
60102

103+
```cpp
104+
class Solution {
105+
public:
106+
int minSubarray(vector<int>& nums, int p) {
107+
int k = 0;
108+
for (int& x : nums) {
109+
k = (k + x) % p;
110+
}
111+
if (k == 0) {
112+
return 0;
113+
}
114+
unordered_map<int, int> last;
115+
last[0] = -1;
116+
int n = nums.size();
117+
int ans = n;
118+
int cur = 0;
119+
for (int i = 0; i < n; ++i) {
120+
cur = (cur + nums[i]) % p;
121+
int target = (cur - k + p) % p;
122+
if (last.count(target)) {
123+
ans = min(ans, i - last[target]);
124+
}
125+
last[cur] = i;
126+
}
127+
return ans == n ? -1 : ans;
128+
}
129+
};
130+
```
131+
132+
### **Go**
133+
134+
```go
135+
func minSubarray(nums []int, p int) int {
136+
k := 0
137+
for _, x := range nums {
138+
k = (k + x) % p
139+
}
140+
if k == 0 {
141+
return 0
142+
}
143+
last := map[int]int{0: -1}
144+
n := len(nums)
145+
ans := n
146+
cur := 0
147+
for i, x := range nums {
148+
cur = (cur + x) % p
149+
target := (cur - k + p) % p
150+
if j, ok := last[target]; ok {
151+
ans = min(ans, i-j)
152+
}
153+
last[cur] = i
154+
}
155+
if ans == n {
156+
return -1
157+
}
158+
return ans
159+
}
160+
161+
func min(a, b int) int {
162+
if a < b {
163+
return a
164+
}
165+
return b
166+
}
61167
```
62168

63169
### **TypeScript**
64170

65171
```ts
66172
function minSubarray(nums: number[], p: number): number {
67-
const n = nums.length;
68-
let mod = 0;
69-
for (let i = 0; i < n; i++) {
70-
mod = (nums[i] + mod) % p;
173+
let k = 0;
174+
for (const x of nums) {
175+
k = (k + x) % p;
71176
}
72-
if (!mod) return 0;
73-
74-
let hashMap = new Map<number, number>();
75-
hashMap.set(0, -1);
177+
if (k === 0) {
178+
return 0;
179+
}
180+
const last = new Map<number, number>();
181+
last.set(0, -1);
182+
const n = nums.length;
76183
let ans = n;
77-
let subMod = 0;
78-
for (let i = 0; i < n; i++) {
79-
let cur = nums[i];
80-
subMod = (subMod + cur) % p;
81-
let target = (subMod - mod + p) % p;
82-
if (hashMap.has(target)) {
83-
let j = hashMap.get(target);
84-
ans = Math.min(i - j, ans);
85-
if (ans == 1 && ans != n) {
86-
return ans;
87-
}
184+
let cur = 0;
185+
for (let i = 0; i < n; ++i) {
186+
cur = (cur + nums[i]) % p;
187+
const target = (cur - k + p) % p;
188+
if (last.has(target)) {
189+
const j = last.get(target)!;
190+
ans = Math.min(ans, i - j);
88191
}
89-
hashMap.set(subMod, i);
192+
last.set(cur, i);
193+
}
194+
if (ans == n) {
195+
return -1;
90196
}
91-
return ans == n ? -1 : ans;
197+
return ans;
92198
}
93199
```
94200

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Solution {
2+
public:
3+
int minSubarray(vector<int>& nums, int p) {
4+
int k = 0;
5+
for (int& x : nums) {
6+
k = (k + x) % p;
7+
}
8+
if (k == 0) {
9+
return 0;
10+
}
11+
unordered_map<int, int> last;
12+
last[0] = -1;
13+
int n = nums.size();
14+
int ans = n;
15+
int cur = 0;
16+
for (int i = 0; i < n; ++i) {
17+
cur = (cur + nums[i]) % p;
18+
int target = (cur - k + p) % p;
19+
if (last.count(target)) {
20+
ans = min(ans, i - last[target]);
21+
}
22+
last[cur] = i;
23+
}
24+
return ans == n ? -1 : ans;
25+
}
26+
};

0 commit comments

Comments
 (0)