Skip to content

Commit 8974512

Browse files
authoredJan 26, 2025··
feat: add solutions to lc problem: No.1590 (doocs#3996)
No.1590.Make Sum Divisible by P
1 parent 2fa1a47 commit 8974512

File tree

4 files changed

+227
-6
lines changed

4 files changed

+227
-6
lines changed
 

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

+78-5
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,17 @@ tags:
8080

8181
### 方法一:前缀和 + 哈希表
8282

83-
我们可以先求出数组 $nums$ 所有元素之和模 $p$ 的值,记为 $k$。如果 $k$ 为 $0$,说明数组 $nums$ 所有元素之和就是 $p$ 的倍数,直接返回 $0$ 即可。
83+
我们可以先求出数组 $\textit{nums}$ 所有元素之和模 $p$ 的值,记为 $k$。如果 $k$ 为 $0$,说明数组 $\textit{nums}$ 所有元素之和就是 $p$ 的倍数,直接返回 $0$ 即可。
8484

8585
如果 $k$ 不为 $0$,我们需要找到一个最短的子数组,使得删除该子数组后,剩余元素之和模 $p$ 的值为 $0$。
8686

87-
我们可以遍历数组 $nums$,维护当前的前缀和模 $p$ 的值,记为 $cur$。用哈希表 $last$ 记录每个前缀和模 $p$ 的值最后一次出现的位置。
87+
我们可以遍历数组 $\textit{nums}$,维护当前的前缀和模 $p$ 的值,记为 $cur$。用哈希表 $last$ 记录每个前缀和模 $p$ 的值最后一次出现的位置。
8888

89-
如果当前存在一个以 $nums[i]$ 结尾的子数组,使得删除该子数组后,剩余元素之和模 $p$ 的值为 $0$。也就是说,我们需要找到此前的一个前缀和模 $p$ 的值为 $target$ 的位置 $j$,使得 $(target + k - cur) \bmod p = 0$。如果找到,我们就可以将 $j + 1$ 到 $i$ 这一段闭区间子数组 $nums[j+1,..i]$ 删除,使得剩余元素之和模 $p$ 的值为 $0$。
89+
如果当前存在一个以 $\textit{nums}[i]$ 结尾的子数组,使得删除该子数组后,剩余元素之和模 $p$ 的值为 $0$。也就是说,我们需要找到此前的一个前缀和模 $p$ 的值为 $target$ 的位置 $j$,使得 $(target + k - cur) \bmod p = 0$。如果找到,我们就可以将 $j + 1$ 到 $i$ 这一段闭区间子数组 $\textit{nums}[j+1,..i]$ 删除,使得剩余元素之和模 $p$ 的值为 $0$。
9090

91-
因此,如果存在一个 $target = (cur - k + p) \bmod p$,那么我们可以更新答案为 $\min(ans, i - j)$。接下来,我们更新 $last[cur]$ 的值为 $i$。继续遍历数组 $nums$,直到遍历结束,即可得到答案。
91+
因此,如果存在一个 $target = (cur - k + p) \bmod p$,那么我们可以更新答案为 $\min(ans, i - j)$。接下来,我们更新 $last[cur]$ 的值为 $i$。继续遍历数组 $\textit{nums}$,直到遍历结束,即可得到答案。
9292

93-
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
93+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。
9494

9595
<!-- tabs:start -->
9696

@@ -234,6 +234,79 @@ function minSubarray(nums: number[], p: number): number {
234234
}
235235
```
236236

237+
#### Rust
238+
239+
```rust
240+
use std::collections::HashMap;
241+
242+
impl Solution {
243+
pub fn min_subarray(nums: Vec<i32>, p: i32) -> i32 {
244+
let mut k = 0;
245+
for &x in &nums {
246+
k = (k + x) % p;
247+
}
248+
if k == 0 {
249+
return 0;
250+
}
251+
252+
let mut last = HashMap::new();
253+
last.insert(0, -1);
254+
let n = nums.len();
255+
let mut ans = n as i32;
256+
let mut cur = 0;
257+
258+
for i in 0..n {
259+
cur = (cur + nums[i]) % p;
260+
let target = (cur - k + p) % p;
261+
if let Some(&prev_idx) = last.get(&target) {
262+
ans = ans.min(i as i32 - prev_idx);
263+
}
264+
last.insert(cur, i as i32);
265+
}
266+
267+
if ans == n as i32 {
268+
-1
269+
} else {
270+
ans
271+
}
272+
}
273+
}
274+
```
275+
276+
#### JavaScript
277+
278+
```js
279+
/**
280+
* @param {number[]} nums
281+
* @param {number} p
282+
* @return {number}
283+
*/
284+
var minSubarray = function (nums, p) {
285+
let k = 0;
286+
for (const x of nums) {
287+
k = (k + x) % p;
288+
}
289+
if (k === 0) {
290+
return 0;
291+
}
292+
const last = new Map();
293+
last.set(0, -1);
294+
const n = nums.length;
295+
let ans = n;
296+
let cur = 0;
297+
for (let i = 0; i < n; ++i) {
298+
cur = (cur + nums[i]) % p;
299+
const target = (cur - k + p) % p;
300+
if (last.has(target)) {
301+
const j = last.get(target);
302+
ans = Math.min(ans, i - j);
303+
}
304+
last.set(cur, i);
305+
}
306+
return ans === n ? -1 : ans;
307+
};
308+
```
309+
237310
<!-- tabs:end -->
238311

239312
<!-- solution:end -->

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

+86-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,19 @@ tags:
6666

6767
<!-- solution:start -->
6868

69-
### Solution 1
69+
### Solution 1: Prefix Sum + Hash Table
70+
71+
First, we calculate the sum of all elements in the array $\textit{nums}$ modulo $p$, denoted as $k$. If $k$ is $0$, it means the sum of all elements in the array $\textit{nums}$ is a multiple of $p$, so we directly return $0$.
72+
73+
If $k$ is not $0$, we need to find the shortest subarray such that removing this subarray makes the sum of the remaining elements modulo $p$ equal to $0$.
74+
75+
We can traverse the array $\textit{nums}$, maintaining the current prefix sum modulo $p$, denoted as $cur$. We use a hash table $last$ to record the last occurrence of each prefix sum modulo $p$.
76+
77+
If there exists a subarray ending at $\textit{nums}[i]$ such that removing this subarray makes the sum of the remaining elements modulo $p$ equal to $0$, we need to find a previous prefix sum modulo $p$ equal to $target$ at position $j$ such that $(target + k - cur) \bmod p = 0$. If found, we can remove the subarray $\textit{nums}[j+1,..i]$ to make the sum of the remaining elements modulo $p$ equal to $0$.
78+
79+
Therefore, if there exists a $target = (cur - k + p) \bmod p$, we can update the answer to $\min(ans, i - j)$. Then, we update $last[cur]$ to $i$. We continue traversing the array $\textit{nums}$ until the end to get the answer.
80+
81+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $\textit{nums}$.
7082

7183
<!-- tabs:start -->
7284

@@ -210,6 +222,79 @@ function minSubarray(nums: number[], p: number): number {
210222
}
211223
```
212224

225+
#### Rust
226+
227+
```rust
228+
use std::collections::HashMap;
229+
230+
impl Solution {
231+
pub fn min_subarray(nums: Vec<i32>, p: i32) -> i32 {
232+
let mut k = 0;
233+
for &x in &nums {
234+
k = (k + x) % p;
235+
}
236+
if k == 0 {
237+
return 0;
238+
}
239+
240+
let mut last = HashMap::new();
241+
last.insert(0, -1);
242+
let n = nums.len();
243+
let mut ans = n as i32;
244+
let mut cur = 0;
245+
246+
for i in 0..n {
247+
cur = (cur + nums[i]) % p;
248+
let target = (cur - k + p) % p;
249+
if let Some(&prev_idx) = last.get(&target) {
250+
ans = ans.min(i as i32 - prev_idx);
251+
}
252+
last.insert(cur, i as i32);
253+
}
254+
255+
if ans == n as i32 {
256+
-1
257+
} else {
258+
ans
259+
}
260+
}
261+
}
262+
```
263+
264+
#### JavaScript
265+
266+
```js
267+
/**
268+
* @param {number[]} nums
269+
* @param {number} p
270+
* @return {number}
271+
*/
272+
var minSubarray = function (nums, p) {
273+
let k = 0;
274+
for (const x of nums) {
275+
k = (k + x) % p;
276+
}
277+
if (k === 0) {
278+
return 0;
279+
}
280+
const last = new Map();
281+
last.set(0, -1);
282+
const n = nums.length;
283+
let ans = n;
284+
let cur = 0;
285+
for (let i = 0; i < n; ++i) {
286+
cur = (cur + nums[i]) % p;
287+
const target = (cur - k + p) % p;
288+
if (last.has(target)) {
289+
const j = last.get(target);
290+
ans = Math.min(ans, i - j);
291+
}
292+
last.set(cur, i);
293+
}
294+
return ans === n ? -1 : ans;
295+
};
296+
```
297+
213298
<!-- tabs:end -->
214299

215300
<!-- solution:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @param {number[]} nums
3+
* @param {number} p
4+
* @return {number}
5+
*/
6+
var minSubarray = function (nums, p) {
7+
let k = 0;
8+
for (const x of nums) {
9+
k = (k + x) % p;
10+
}
11+
if (k === 0) {
12+
return 0;
13+
}
14+
const last = new Map();
15+
last.set(0, -1);
16+
const n = nums.length;
17+
let ans = n;
18+
let cur = 0;
19+
for (let i = 0; i < n; ++i) {
20+
cur = (cur + nums[i]) % p;
21+
const target = (cur - k + p) % p;
22+
if (last.has(target)) {
23+
const j = last.get(target);
24+
ans = Math.min(ans, i - j);
25+
}
26+
last.set(cur, i);
27+
}
28+
return ans === n ? -1 : ans;
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use std::collections::HashMap;
2+
3+
impl Solution {
4+
pub fn min_subarray(nums: Vec<i32>, p: i32) -> i32 {
5+
let mut k = 0;
6+
for &x in &nums {
7+
k = (k + x) % p;
8+
}
9+
if k == 0 {
10+
return 0;
11+
}
12+
13+
let mut last = HashMap::new();
14+
last.insert(0, -1);
15+
let n = nums.len();
16+
let mut ans = n as i32;
17+
let mut cur = 0;
18+
19+
for i in 0..n {
20+
cur = (cur + nums[i]) % p;
21+
let target = (cur - k + p) % p;
22+
if let Some(&prev_idx) = last.get(&target) {
23+
ans = ans.min(i as i32 - prev_idx);
24+
}
25+
last.insert(cur, i as i32);
26+
}
27+
28+
if ans == n as i32 {
29+
-1
30+
} else {
31+
ans
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)
Please sign in to comment.