Skip to content

Commit 2c6cd87

Browse files
authored
feat: add solutions to lc problems: No.1004,2024 (#2574)
* No.1004.Max Consecutive Ones III * No.2024.Maximize the Confusion of an Exam
1 parent 353828a commit 2c6cd87

File tree

13 files changed

+351
-335
lines changed

13 files changed

+351
-335
lines changed

solution/1000-1099/1004.Max Consecutive Ones III/README.md

+50-54
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,13 @@
4242

4343
### 方法一:滑动窗口
4444

45-
定义一个滑动窗口,窗口内的 $0$ 的个数不超过 $k$,窗口的右边界不断向右移动,当窗口内的 $0$ 的个数超过 $k$ 时,窗口的左边界向右移动,直到窗口内的 $0$ 的个数不超过 $k$ 为止。
45+
我们定义一个滑动窗口,窗口内的 $0$ 的个数不超过 $k$,窗口的右边界不断向右移动,当窗口内的 $0$ 的个数超过 $k$ 时,窗口的左边界向右移动,直到窗口内的 $0$ 的个数不超过 $k$ 为止。
4646

47-
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组的长度
47+
时间复杂度 $O(n)$,其中 $n$ 为数组的长度。空间复杂度 $O(1)$。
4848

4949
相似题目:
5050

5151
- [487. 最大连续 1 的个数 II](https://github.com/doocs/leetcode/blob/main/solution/0400-0499/0487.Max%20Consecutive%20Ones%20II/README.md)
52-
53-
以下是滑动窗口的优化版本。
54-
55-
维护一个单调变长的窗口。这种窗口经常出现在寻求“最大窗口”的问题中:因为求的是“最大”,所以我们没有必要缩短窗口,于是代码就少了缩短窗口的部分;从另一个角度讲,本题里的 K 是资源数,一旦透支,窗口就不能再增长了。
56-
57-
- l 是窗口左端点,负责移动起始位置
58-
- r 是窗口右端点,负责扩展窗口
59-
- k 是资源数,每次要替换 0,k 减 1,同时 r 向右移动
60-
- `r++` 每次都会执行,`l++` 只有资源 `k < 0` 时才触发,因此 `r - l` 的值只会单调递增(或保持不变)
61-
- 移动左端点时,如果当前元素是 0,说明可以释放一个资源,k 加 1
62-
63-
相似题目:
64-
6552
- [2024. 考试的最大困扰度](https://github.com/doocs/leetcode/blob/main/solution/2000-2099/2024.Maximize%20the%20Confusion%20of%20an%20Exam/README.md)
6653

6754
<!-- tabs:start -->
@@ -148,43 +135,33 @@ func longestOnes(nums []int, k int) int {
148135
```ts
149136
function longestOnes(nums: number[], k: number): number {
150137
const n = nums.length;
151-
let l = 0;
152-
for (const num of nums) {
153-
if (num === 0) {
154-
k--;
155-
}
156-
if (k < 0 && nums[l++] === 0) {
157-
k++;
138+
let [ans, cnt, j] = [0, 0, 0];
139+
for (let i = 0; i < n; ++i) {
140+
cnt += nums[i] ^ 1;
141+
while (cnt > k) {
142+
cnt -= nums[j++] ^ 1;
158143
}
144+
ans = Math.max(ans, i - j + 1);
159145
}
160-
return n - l;
161-
}
162-
```
163-
164-
```rust
165-
impl Solution {
166-
pub fn longest_ones(nums: Vec<i32>, mut k: i32) -> i32 {
167-
let n = nums.len();
168-
let mut l = 0;
169-
for num in nums.iter() {
170-
if num == &0 {
171-
k -= 1;
172-
}
173-
if k < 0 {
174-
if nums[l] == 0 {
175-
k += 1;
176-
}
177-
l += 1;
178-
}
179-
}
180-
(n - l) as i32
181-
}
146+
return ans;
182147
}
183148
```
184149

185150
<!-- tabs:end -->
186151

187-
### 方法二
152+
### 方法二:滑动窗口(优化)
153+
154+
以下是滑动窗口的优化版本。
155+
156+
维护一个单调变长的窗口。这种窗口经常出现在寻求“最大窗口”的问题中:因为求的是“最大”,所以我们没有必要缩短窗口,于是代码就少了缩短窗口的部分;从另一个角度讲,本题里的 K 是资源数,一旦透支,窗口就不能再增长了。
157+
158+
- l 是窗口左端点,负责移动起始位置
159+
- r 是窗口右端点,负责扩展窗口
160+
- k 是资源数,每次要替换 0,k 减 1,同时 r 向右移动
161+
- `r++` 每次都会执行,`l++` 只有资源 `k < 0` 时才触发,因此 `r - l` 的值只会单调递增(或保持不变)
162+
- 移动左端点时,如果当前元素是 0,说明可以释放一个资源,k 加 1
163+
164+
时间复杂度 $O(n)$,其中 $n$ 为数组的长度。空间复杂度 $O(1)$。
188165

189166
<!-- tabs:start -->
190167

@@ -257,17 +234,36 @@ func longestOnes(nums []int, k int) int {
257234
function longestOnes(nums: number[], k: number): number {
258235
const n = nums.length;
259236
let l = 0;
260-
let res = k;
261-
const count = [0, 0];
262-
for (let r = 0; r < n; r++) {
263-
count[nums[r]]++;
264-
res = Math.max(res, r - l);
265-
while (count[0] > k) {
266-
count[nums[l]]--;
267-
l++;
237+
for (const num of nums) {
238+
if (num === 0) {
239+
k--;
240+
}
241+
if (k < 0 && nums[l++] === 0) {
242+
k++;
243+
}
244+
}
245+
return n - l;
246+
}
247+
```
248+
249+
```rust
250+
impl Solution {
251+
pub fn longest_ones(nums: Vec<i32>, mut k: i32) -> i32 {
252+
let n = nums.len();
253+
let mut l = 0;
254+
for num in nums.iter() {
255+
if num == &0 {
256+
k -= 1;
257+
}
258+
if k < 0 {
259+
if nums[l] == 0 {
260+
k += 1;
261+
}
262+
l += 1;
263+
}
268264
}
265+
(n - l) as i32
269266
}
270-
return Math.max(res, n - l);
271267
}
272268
```
273269

solution/1000-1099/1004.Max Consecutive Ones III/README_EN.md

+58-40
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,16 @@ Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.
3737

3838
## Solutions
3939

40-
### Solution 1
40+
### Solution 1: Sliding Window
41+
42+
We define a sliding window, the number of $0$s in the window does not exceed $k$. The right boundary of the window keeps moving to the right. When the number of $0$s in the window exceeds $k$, the left boundary of the window moves to the right until the number of $0$s in the window does not exceed $k$.
43+
44+
The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$.
45+
46+
Similar problems:
47+
48+
- [487. Max Consecutive Ones II](https://github.com/doocs/leetcode/blob/main/solution/0400-0499/0487.Max%20Consecutive%20Ones%20II/README_EN.md)
49+
- [2024. Maximize the Confusion of an Exam](https://github.com/doocs/leetcode/blob/main/solution/2000-2099/2024.Maximize%20the%20Confusion%20of%20an%20Exam/README_EN.md)
4150

4251
<!-- tabs:start -->
4352

@@ -123,43 +132,33 @@ func longestOnes(nums []int, k int) int {
123132
```ts
124133
function longestOnes(nums: number[], k: number): number {
125134
const n = nums.length;
126-
let l = 0;
127-
for (const num of nums) {
128-
if (num === 0) {
129-
k--;
135+
let [ans, cnt, j] = [0, 0, 0];
136+
for (let i = 0; i < n; ++i) {
137+
cnt += nums[i] ^ 1;
138+
while (cnt > k) {
139+
cnt -= nums[j++] ^ 1;
130140
}
131-
if (k < 0 && nums[l++] === 0) {
132-
k++;
133-
}
134-
}
135-
return n - l;
136-
}
137-
```
138-
139-
```rust
140-
impl Solution {
141-
pub fn longest_ones(nums: Vec<i32>, mut k: i32) -> i32 {
142-
let n = nums.len();
143-
let mut l = 0;
144-
for num in nums.iter() {
145-
if num == &0 {
146-
k -= 1;
147-
}
148-
if k < 0 {
149-
if nums[l] == 0 {
150-
k += 1;
151-
}
152-
l += 1;
153-
}
154-
}
155-
(n - l) as i32
141+
ans = Math.max(ans, i - j + 1);
156142
}
143+
return ans;
157144
}
158145
```
159146

160147
<!-- tabs:end -->
161148

162-
### Solution 2
149+
### Solution 2: Sliding Window (Optimized)
150+
151+
Below is the optimized version of the sliding window.
152+
153+
Maintain a monotonically variable-length window. This kind of window often appears in problems seeking the "maximum window": because we are seeking the "maximum", there is no need to shorten the window, so the code lacks the part to shorten the window; from another perspective, the K in this problem is the number of resources, once overdrawn, the window can no longer grow.
154+
155+
- `l` is the left endpoint of the window, responsible for moving the starting position
156+
- `r` is the right endpoint of the window, responsible for expanding the window
157+
- `k` is the number of resources, each time a 0 needs to be replaced, `k` decreases by 1, and `r` moves to the right at the same time
158+
- `r++` will be executed every time, `l++` is only triggered when the resource `k < 0`, therefore the value of `r - l` will only increase monotonically (or remain unchanged)
159+
- When moving the left endpoint, if the current element is 0, it means that a resource can be released, `k` increases by 1
160+
161+
The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$.
163162

164163
<!-- tabs:start -->
165164

@@ -232,17 +231,36 @@ func longestOnes(nums []int, k int) int {
232231
function longestOnes(nums: number[], k: number): number {
233232
const n = nums.length;
234233
let l = 0;
235-
let res = k;
236-
const count = [0, 0];
237-
for (let r = 0; r < n; r++) {
238-
count[nums[r]]++;
239-
res = Math.max(res, r - l);
240-
while (count[0] > k) {
241-
count[nums[l]]--;
242-
l++;
234+
for (const num of nums) {
235+
if (num === 0) {
236+
k--;
237+
}
238+
if (k < 0 && nums[l++] === 0) {
239+
k++;
240+
}
241+
}
242+
return n - l;
243+
}
244+
```
245+
246+
```rust
247+
impl Solution {
248+
pub fn longest_ones(nums: Vec<i32>, mut k: i32) -> i32 {
249+
let n = nums.len();
250+
let mut l = 0;
251+
for num in nums.iter() {
252+
if num == &0 {
253+
k -= 1;
254+
}
255+
if k < 0 {
256+
if nums[l] == 0 {
257+
k += 1;
258+
}
259+
l += 1;
260+
}
243261
}
262+
(n - l) as i32
244263
}
245-
return Math.max(res, n - l);
246264
}
247265
```
248266

Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
function longestOnes(nums: number[], k: number): number {
22
const n = nums.length;
3-
let l = 0;
4-
for (const num of nums) {
5-
if (num === 0) {
6-
k--;
7-
}
8-
if (k < 0 && nums[l++] === 0) {
9-
k++;
3+
let [ans, cnt, j] = [0, 0, 0];
4+
for (let i = 0; i < n; ++i) {
5+
cnt += nums[i] ^ 1;
6+
while (cnt > k) {
7+
cnt -= nums[j++] ^ 1;
108
}
9+
ans = Math.max(ans, i - j + 1);
1110
}
12-
return n - l;
11+
return ans;
1312
}
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
function longestOnes(nums: number[], k: number): number {
22
const n = nums.length;
33
let l = 0;
4-
let res = k;
5-
const count = [0, 0];
6-
for (let r = 0; r < n; r++) {
7-
count[nums[r]]++;
8-
res = Math.max(res, r - l);
9-
while (count[0] > k) {
10-
count[nums[l]]--;
11-
l++;
4+
for (const num of nums) {
5+
if (num === 0) {
6+
k--;
7+
}
8+
if (k < 0 && nums[l++] === 0) {
9+
k++;
1210
}
1311
}
14-
return Math.max(res, n - l);
12+
return n - l;
1513
}

0 commit comments

Comments
 (0)