Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 070dbb6

Browse files
feat: add solutions to lc problem: No.3356 (doocs#4413)
No.3356.Zero Array Transformation II
1 parent 8ec2624 commit 070dbb6

File tree

3 files changed

+161
-2
lines changed

3 files changed

+161
-2
lines changed

‎solution/3300-3399/3356.Zero Array Transformation II/README.md‎

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,21 @@ tags:
109109

110110
<!-- solution:start -->
111111

112-
### 方法一
112+
### 方法一:差分数组 + 二分查找
113+
114+
我们注意到,查询的个数越多,越容易使得数组变成零数组,这存在单调性。因此,我们可以二分枚举查询的个数,判断在前 k 个查询下,是否可以将数组变成零数组。
115+
116+
我们定义二分查找的左边界 $l$ 和右边界 $r,ドル初始时 $l = 0,ドル $r = m + 1,ドル其中 $m$ 是查询的个数。我们定义一个函数 $\text{check}(k),ドル表示在前 $k$ 个查询下,是否可以将数组变成零数组。我们可以使用差分数组来维护每个元素的值。
117+
118+
定义一个长度为 $n + 1$ 的数组 $d,ドル初始值全部为 0ドル$。对于前 $k$ 个查询的每个查询 $[l, r],ドル我们将 $d[l]$ 加 1ドル,ドル将 $d[r + 1]$ 减 1ドル$。
119+
120+
然后我们遍历数组 $d$ 在 $[0, n - 1]$ 范围内的每个元素,累加前缀和 $s,ドル如果 $\textit{nums}[i] > s,ドル说明 $\textit{nums}$ 不能转换为零数组,返回 $\textit{false}$。
121+
122+
我们在二分查找的过程中,如果 $\text{check}(k)$ 返回 $\text{true},ドル说明可以将数组变成零数组,我们就将右边界 $r$ 更新为 $k,ドル否则将左边界 $l$ 更新为 $k + 1$。
123+
124+
最后,我们判断 $l$ 是否大于 $m,ドル如果是,则返回 -1,否则返回 $l$。
125+
126+
时间复杂度 $O((n + m) \times \log m),ドル空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为数组 $\textit{nums}$ 和 $\textit{queries}$ 的长度。
113127

114128
<!-- tabs:start -->
115129

@@ -278,6 +292,50 @@ function minZeroArray(nums: number[], queries: number[][]): number {
278292
}
279293
```
280294

295+
#### Rust
296+
297+
```rust
298+
impl Solution {
299+
pub fn min_zero_array(nums: Vec<i32>, queries: Vec<Vec<i32>>) -> i32 {
300+
let n = nums.len();
301+
let m = queries.len();
302+
let mut d: Vec<i64> = vec![0; n + 1];
303+
let (mut l, mut r) = (0_usize, m + 1);
304+
305+
let check = |k: usize, d: &mut Vec<i64>| -> bool {
306+
d.fill(0);
307+
for i in 0..k {
308+
let (l, r, val) = (
309+
queries[i][0] as usize,
310+
queries[i][1] as usize,
311+
queries[i][2] as i64,
312+
);
313+
d[l] += val;
314+
d[r + 1] -= val;
315+
}
316+
let mut s: i64 = 0;
317+
for i in 0..n {
318+
s += d[i];
319+
if nums[i] as i64 > s {
320+
return false;
321+
}
322+
}
323+
true
324+
};
325+
326+
while l < r {
327+
let mid = (l + r) >> 1;
328+
if check(mid, &mut d) {
329+
r = mid;
330+
} else {
331+
l = mid + 1;
332+
}
333+
}
334+
if l > m { -1 } else { l as i32 }
335+
}
336+
}
337+
```
338+
281339
<!-- tabs:end -->
282340

283341
<!-- solution:end -->

‎solution/3300-3399/3356.Zero Array Transformation II/README_EN.md‎

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,21 @@ tags:
106106

107107
<!-- solution:start -->
108108

109-
### Solution 1
109+
### Solution 1: Difference Array + Binary Search
110+
111+
We notice that the more queries we use, the easier it is to turn the array into a zero array, which shows monotonicity. Therefore, we can use binary search to enumerate the number of queries and check whether the array can be turned into a zero array after the first $k$ queries.
112+
113+
We define the left boundary $l$ and right boundary $r$ for binary search, initially $l = 0,ドル $r = m + 1,ドル where $m$ is the number of queries. We define a function $\text{check}(k)$ to indicate whether the array can be turned into a zero array after the first $k$ queries. We can use a difference array to maintain the value of each element.
114+
115+
Define an array $d$ of length $n + 1,ドル initialized to all 0ドル$. For each of the first $k$ queries $[l, r, val],ドル we add $val$ to $d[l]$ and subtract $val$ from $d[r + 1]$.
116+
117+
Then we iterate through the array $d$ in the range $[0, n - 1],ドル accumulating the prefix sum $s$. If $\textit{nums}[i] > s,ドル it means $\textit{nums}$ cannot be transformed into a zero array, so we return $\textit{false}$.
118+
119+
During the binary search, if $\text{check}(k)$ returns $\text{true},ドル it means the array can be turned into a zero array, so we update the right boundary $r$ to $k$; otherwise, we update the left boundary $l$ to $k + 1$.
120+
121+
Finally, we check whether $l > m$. If so, return -1; otherwise, return $l$.
122+
123+
The time complexity is $O((n + m) \times \log m),ドル and the space complexity is $O(n),ドル where $n$ and $m$ are the lengths of the array $\textit{nums}$ and $\textit{queries},ドル respectively.
110124

111125
<!-- tabs:start -->
112126

@@ -275,6 +289,50 @@ function minZeroArray(nums: number[], queries: number[][]): number {
275289
}
276290
```
277291

292+
#### Rust
293+
294+
```rust
295+
impl Solution {
296+
pub fn min_zero_array(nums: Vec<i32>, queries: Vec<Vec<i32>>) -> i32 {
297+
let n = nums.len();
298+
let m = queries.len();
299+
let mut d: Vec<i64> = vec![0; n + 1];
300+
let (mut l, mut r) = (0_usize, m + 1);
301+
302+
let check = |k: usize, d: &mut Vec<i64>| -> bool {
303+
d.fill(0);
304+
for i in 0..k {
305+
let (l, r, val) = (
306+
queries[i][0] as usize,
307+
queries[i][1] as usize,
308+
queries[i][2] as i64,
309+
);
310+
d[l] += val;
311+
d[r + 1] -= val;
312+
}
313+
let mut s: i64 = 0;
314+
for i in 0..n {
315+
s += d[i];
316+
if nums[i] as i64 > s {
317+
return false;
318+
}
319+
}
320+
true
321+
};
322+
323+
while l < r {
324+
let mid = (l + r) >> 1;
325+
if check(mid, &mut d) {
326+
r = mid;
327+
} else {
328+
l = mid + 1;
329+
}
330+
}
331+
if l > m { -1 } else { l as i32 }
332+
}
333+
}
334+
```
335+
278336
<!-- tabs:end -->
279337

280338
<!-- solution:end -->
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
impl Solution {
2+
pub fn min_zero_array(nums: Vec<i32>, queries: Vec<Vec<i32>>) -> i32 {
3+
let n = nums.len();
4+
let m = queries.len();
5+
let mut d: Vec<i64> = vec![0; n + 1];
6+
let (mut l, mut r) = (0_usize, m + 1);
7+
8+
let check = |k: usize, d: &mut Vec<i64>| -> bool {
9+
d.fill(0);
10+
for i in 0..k {
11+
let (l, r, val) = (
12+
queries[i][0] as usize,
13+
queries[i][1] as usize,
14+
queries[i][2] as i64,
15+
);
16+
d[l] += val;
17+
d[r + 1] -= val;
18+
}
19+
let mut s: i64 = 0;
20+
for i in 0..n {
21+
s += d[i];
22+
if nums[i] as i64 > s {
23+
return false;
24+
}
25+
}
26+
true
27+
};
28+
29+
while l < r {
30+
let mid = (l + r) >> 1;
31+
if check(mid, &mut d) {
32+
r = mid;
33+
} else {
34+
l = mid + 1;
35+
}
36+
}
37+
if l > m {
38+
-1
39+
} else {
40+
l as i32
41+
}
42+
}
43+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /