Skip to content

Commit 5c0658f

Browse files
committed
feat: add solutions to lc problem: No.0487
No.0487.Max Consecutive Ones II
1 parent 8d4fb98 commit 5c0658f

File tree

6 files changed

+458
-170
lines changed

6 files changed

+458
-170
lines changed

solution/0400-0499/0487.Max Consecutive Ones II/README.md

Lines changed: 203 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,21 @@
4343

4444
<!-- 这里可写通用的实现逻辑 -->
4545

46-
`prefix[i]` 数组表示以 $i$ 结尾往前累计的最大连续 1 的个数,`suffix[i]` 数组表示以 $i$ 开头往后累计的最大连续 1 的个数。
46+
**方法一:预处理 + 枚举**
4747

48-
遍历 `nums` 数组每个为 0 的位置,则位置 $i$ 的最大连续 1 的个数为 `1 + prefix[i-1] + suffix[i+1]`
48+
定义 `left`, `right` 数组表示以第 $i$ 个元素结尾(开头),往前(往后)累计的最大连续 $1$ 的个数
4949

50-
当然,如果 `nums` 数组没有 0,即所有元素都是 1,那么结果即为 `nums` 数组的长度。
50+
先遍历 `nums`,预处理出 `left``right`
51+
52+
然后枚举 `nums` 每个位置 $i$,统计以 $i$ 为分界点,左右两边最大连续 $1$ 的个数之和,取最大值即可。
53+
54+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 `nums` 的长度。
55+
56+
**方法二:滑动窗口**
57+
58+
找出最大的窗口,使得窗口内的 $0$ 的个数不超过 $1$ 个。
59+
60+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为 `nums` 的长度。
5161

5262
<!-- tabs:start -->
5363

@@ -58,95 +68,228 @@
5868
```python
5969
class Solution:
6070
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
71+
ans = nums.count(1)
6172
n = len(nums)
62-
prefix = [0] * n
63-
suffix = [0] * n
64-
res = 0
65-
for i in range(n):
66-
if i == 0:
67-
prefix[i] = nums[i]
68-
else:
69-
prefix[i] = 0 if nums[i] == 0 else prefix[i - 1] + 1
70-
res = max(res, prefix[i])
71-
73+
left = [0] * n
74+
right = [0] * n
75+
for i, v in enumerate(nums):
76+
if v:
77+
left[i] = 1 if i == 0 else left[i - 1] + 1
7278
for i in range(n - 1, -1, -1):
73-
if i == n - 1:
74-
suffix[i] = nums[i]
75-
else:
76-
suffix[i] = 0 if nums[i] == 0 else suffix[i + 1] + 1
77-
78-
for i in range(n):
79-
if nums[i] == 0:
80-
t = 1
81-
if i > 0:
82-
t += prefix[i - 1]
83-
if i < n - 1:
84-
t += suffix[i + 1]
85-
res = max(res, t)
86-
return res
79+
v = nums[i]
80+
if v:
81+
right[i] = 1 if i == n - 1 else right[i + 1] + 1
82+
ans = 0
83+
for i, v in enumerate(nums):
84+
t = 0
85+
if i:
86+
t += left[i - 1]
87+
if i < n - 1:
88+
t += right[i + 1]
89+
ans = max(ans, t + 1)
90+
return ans
91+
```
92+
93+
```python
94+
class Solution:
95+
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
96+
ans = 1
97+
cnt = j = 0
98+
for i, v in enumerate(nums):
99+
if v == 0:
100+
cnt += 1
101+
while cnt > 1:
102+
if nums[j] == 0:
103+
cnt -= 1
104+
j += 1
105+
ans = max(ans, i - j + 1)
106+
return ans
87107
```
88108

89109
### **Java**
90110

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

93-
- 双指针,时间复杂度 $O(n^2)$,空间复杂度 $O(1)$
94-
95113
```java
96114
class Solution {
97115
public int findMaxConsecutiveOnes(int[] nums) {
98116
int n = nums.length;
99-
int res = 0;
117+
int[] left = new int[n];
118+
int[] right = new int[n];
119+
for (int i = 0; i < n; ++i) {
120+
if (nums[i] == 1) {
121+
left[i] = i == 0 ? 1 : left[i - 1] + 1;
122+
}
123+
}
124+
for (int i = n - 1; i >= 0; --i) {
125+
if (nums[i] == 1) {
126+
right[i] = i == n - 1 ? 1 : right[i + 1] + 1;
127+
}
128+
}
129+
int ans = 0;
100130
for (int i = 0; i < n; ++i) {
101-
int cnt = 1;
102-
int j = i;
103-
while (j < n && (cnt > 0 || nums[j] == 1)) {
104-
if (nums[j] == 0) --cnt;
105-
++j;
131+
int t = 0;
132+
if (i > 0) {
133+
t += left[i - 1];
134+
}
135+
if (i < n - 1) {
136+
t += right[i + 1];
106137
}
107-
res = Math.max(res, j - i);
138+
ans = Math.max(ans, t + 1);
108139
}
109-
return res;
140+
return ans;
110141
}
111142
}
112143
```
113144

114-
- 辅助数组,时间复杂度 $O(n)$,空间复杂度 $O(n)$
115-
116145
```java
117146
class Solution {
118147
public int findMaxConsecutiveOnes(int[] nums) {
119-
int n = nums.length;
148+
int j = 0, cnt = 0;
149+
int ans = 1;
150+
for (int i = 0; i < nums.length; ++i) {
151+
if (nums[i] == 0) {
152+
++cnt;
153+
}
154+
while (cnt > 1) {
155+
if (nums[j++] == 0) {
156+
--cnt;
157+
}
158+
}
159+
ans = Math.max(ans, i - j + 1);
160+
}
161+
return ans;
162+
}
163+
}
164+
```
120165

121-
int[] prefix = new int[n];
122-
int[] suffix = new int[n];
166+
### **C++**
123167

124-
int res = 0;
168+
```cpp
169+
class Solution {
170+
public:
171+
int findMaxConsecutiveOnes(vector<int>& nums) {
172+
int n = nums.size();
173+
vector<int> left(n), right(n);
125174
for (int i = 0; i < n; ++i) {
126-
if (i == 0)
127-
prefix[0] = nums[0];
128-
else
129-
prefix[i] = nums[i] == 0 ? 0 : prefix[i - 1] + 1;
130-
res = Math.max(res, prefix[i]);
175+
if (nums[i]) {
176+
left[i] = i == 0 ? 1 : left[i - 1] + 1;
177+
}
131178
}
132-
133-
for (int i = n - 1; i >= 0; --i) {
134-
if (i == n - 1)
135-
suffix[n - 1] = nums[n - 1];
136-
else
137-
suffix[i] = nums[i] == 0 ? 0 : suffix[i + 1] + 1;
179+
for (int i = n - 1; ~i; --i) {
180+
if (nums[i]) {
181+
right[i] = i == n - 1 ? 1 : right[i + 1] + 1;
182+
}
138183
}
139-
184+
int ans = 0;
140185
for (int i = 0; i < n; ++i) {
186+
int t = 0;
187+
if (i) {
188+
t += left[i - 1];
189+
}
190+
if (i < n - 1) {
191+
t += right[i + 1];
192+
}
193+
ans = max(ans, t + 1);
194+
}
195+
return ans;
196+
}
197+
};
198+
```
199+
200+
```cpp
201+
class Solution {
202+
public:
203+
int findMaxConsecutiveOnes(vector<int>& nums) {
204+
int ans = 1;
205+
int cnt = 0, j = 0;
206+
for (int i = 0; i < nums.size(); ++i) {
141207
if (nums[i] == 0) {
142-
int t = 1;
143-
if (i > 0) t += prefix[i - 1];
144-
if (i < n - 1) t += suffix[i + 1];
145-
res = Math.max(res, t);
208+
++cnt;
209+
}
210+
while (cnt > 1) {
211+
if (nums[j++] == 0) {
212+
--cnt;
213+
}
146214
}
215+
ans = max(ans, i - j + 1);
147216
}
148-
return res;
217+
return ans;
149218
}
219+
};
220+
```
221+
222+
### **Go**
223+
224+
```go
225+
func findMaxConsecutiveOnes(nums []int) int {
226+
n := len(nums)
227+
left := make([]int, n)
228+
right := make([]int, n)
229+
for i, v := range nums {
230+
if v == 1 {
231+
if i == 0 {
232+
left[i] = 1
233+
} else {
234+
left[i] = left[i-1] + 1
235+
}
236+
}
237+
}
238+
for i := n - 1; i >= 0; i-- {
239+
if nums[i] == 1 {
240+
if i == n-1 {
241+
right[i] = 1
242+
} else {
243+
right[i] = right[i+1] + 1
244+
}
245+
}
246+
}
247+
ans := 0
248+
for i := range nums {
249+
t := 0
250+
if i > 0 {
251+
t += left[i-1]
252+
}
253+
if i < n-1 {
254+
t += right[i+1]
255+
}
256+
ans = max(ans, t+1)
257+
}
258+
return ans
259+
}
260+
261+
func max(a, b int) int {
262+
if a > b {
263+
return a
264+
}
265+
return b
266+
}
267+
```
268+
269+
```go
270+
func findMaxConsecutiveOnes(nums []int) int {
271+
ans := 1
272+
j, cnt := 0, 0
273+
for i, v := range nums {
274+
if v == 0 {
275+
cnt++
276+
}
277+
for cnt > 1 {
278+
if nums[j] == 0 {
279+
cnt--
280+
}
281+
j++
282+
}
283+
ans = max(ans, i-j+1)
284+
}
285+
return ans
286+
}
287+
288+
func max(a, b int) int {
289+
if a > b {
290+
return a
291+
}
292+
return b
150293
}
151294
```
152295

0 commit comments

Comments
 (0)