|
43 | 43 |
|
44 | 44 | <!-- 这里可写通用的实现逻辑 -->
|
45 | 45 |
|
46 |
| -用 `prefix[i]` 数组表示以 $i$ 结尾往前累计的最大连续 1 的个数,`suffix[i]` 数组表示以 $i$ 开头往后累计的最大连续 1 的个数。 |
| 46 | +**方法一:预处理 + 枚举** |
47 | 47 |
|
48 |
| -遍历 `nums` 数组每个为 0 的位置,则位置 $i$ 的最大连续 1 的个数为 `1 + prefix[i-1] + suffix[i+1]`。 |
| 48 | +定义 `left`, `right` 数组表示以第 $i$ 个元素结尾(开头),往前(往后)累计的最大连续 $1$ 的个数。 |
49 | 49 |
|
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` 的长度。 |
51 | 61 |
|
52 | 62 | <!-- tabs:start -->
|
53 | 63 |
|
|
58 | 68 | ```python
|
59 | 69 | class Solution:
|
60 | 70 | def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
|
| 71 | + ans = nums.count(1) |
61 | 72 | 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 |
72 | 78 | 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 |
87 | 107 | ```
|
88 | 108 |
|
89 | 109 | ### **Java**
|
90 | 110 |
|
91 | 111 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
92 | 112 |
|
93 |
| -- 双指针,时间复杂度 $O(n^2)$,空间复杂度 $O(1)$ |
94 |
| - |
95 | 113 | ```java
|
96 | 114 | class Solution {
|
97 | 115 | public int findMaxConsecutiveOnes(int[] nums) {
|
98 | 116 | 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; |
100 | 130 | 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]; |
106 | 137 | }
|
107 |
| - res = Math.max(res, j - i); |
| 138 | + ans = Math.max(ans, t + 1); |
108 | 139 | }
|
109 |
| - return res; |
| 140 | + return ans; |
110 | 141 | }
|
111 | 142 | }
|
112 | 143 | ```
|
113 | 144 |
|
114 |
| -- 辅助数组,时间复杂度 $O(n)$,空间复杂度 $O(n)$ |
115 |
| - |
116 | 145 | ```java
|
117 | 146 | class Solution {
|
118 | 147 | 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 | +``` |
120 | 165 |
|
121 |
| - int[] prefix = new int[n]; |
122 |
| - int[] suffix = new int[n]; |
| 166 | +### **C++** |
123 | 167 |
|
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); |
125 | 174 | 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 | + } |
131 | 178 | }
|
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 | + } |
138 | 183 | }
|
139 |
| - |
| 184 | + int ans = 0; |
140 | 185 | 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) { |
141 | 207 | 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 | + } |
146 | 214 | }
|
| 215 | + ans = max(ans, i - j + 1); |
147 | 216 | }
|
148 |
| - return res; |
| 217 | + return ans; |
149 | 218 | }
|
| 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 |
150 | 293 | }
|
151 | 294 | ```
|
152 | 295 |
|
|
0 commit comments