50
50
51
51
### 方法一:枚举
52
52
53
- 枚举删除的位置 $i$,那么每一个位置 $i$ 的最长子数组长度为 $i$ 左边连续的 $1$ 的个数加上 $i$ 右边连续的 $1$ 的个数。
53
+ 我们可以枚举每个删除的位置 $i$,然后计算左侧和右侧的连续 1 的个数,最后取最大值 。
54
54
55
- 因此,我们可以先遍历一遍数组,统计每个位置 $i$ 左边连续的 $1$ 的个数,记录在 ` left ` 数组;然后再从右向左遍历一遍数组,统计每个位置 $i$ 右边连续的 $1$ 的个数,记录在 ` right ` 数组,最后枚举删除的位置 $i$,求出最大值即可 。
55
+ 具体地,我们使用两个长度为 $n+1$ 的数组 $left$ 和 $right$,其中 $ left[ i ] $ 表示以 $nums [ i-1 ] $ 结尾的连续 $1$ 的个数,而 $ right[ i ] $ 表示以 $nums [ i ] $ 开头的连续 $1$ 的个数 。
56
56
57
- 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 ` nums ` 的长度。
57
+ 最终答案即为 $\max_ {0 \leq i < n} \{ left[ i] + right[ i+1] \} $。
58
+
59
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
58
60
59
61
<!-- tabs:start -->
60
62
61
63
``` python
62
64
class Solution :
63
65
def longestSubarray (self , nums : List[int ]) -> int :
64
66
n = len (nums)
65
- left = [0 ] * n
66
- right = [0 ] * n
67
- for i in range ( 1 , n ):
68
- if nums[i - 1 ] == 1 :
67
+ left = [0 ] * (n + 1 )
68
+ right = [0 ] * (n + 1 )
69
+ for i, x in enumerate (nums, 1 ):
70
+ if x :
69
71
left[i] = left[i - 1 ] + 1
70
- for i in range (n - 2 , - 1 , - 1 ):
71
- if nums[i + 1 ] == 1 :
72
+ for i in range (n - 1 , - 1 , - 1 ):
73
+ if nums[i] :
72
74
right[i] = right[i + 1 ] + 1
73
- return max (a + b for a, b in zip (left, right ))
75
+ return max (left[i] + right[i + 1 ] for i in range (n ))
74
76
```
75
77
76
78
``` java
77
79
class Solution {
78
80
public int longestSubarray (int [] nums ) {
79
81
int n = nums. length;
80
- int [] left = new int [n];
81
- int [] right = new int [n];
82
- for (int i = 1 ; i < n; ++ i) {
82
+ int [] left = new int [n + 1 ];
83
+ int [] right = new int [n + 1 ];
84
+ for (int i = 1 ; i <= n; ++ i) {
83
85
if (nums[i - 1 ] == 1 ) {
84
86
left[i] = left[i - 1 ] + 1 ;
85
87
}
86
88
}
87
- for (int i = n - 2 ; i >= 0 ; -- i) {
88
- if (nums[i + 1 ] == 1 ) {
89
+ for (int i = n - 1 ; i >= 0 ; -- i) {
90
+ if (nums[i] == 1 ) {
89
91
right[i] = right[i + 1 ] + 1 ;
90
92
}
91
93
}
92
94
int ans = 0 ;
93
95
for (int i = 0 ; i < n; ++ i) {
94
- ans = Math . max(ans, left[i] + right[i]);
96
+ ans = Math . max(ans, left[i] + right[i + 1 ]);
95
97
}
96
98
return ans;
97
99
}
@@ -103,47 +105,158 @@ class Solution {
103
105
public:
104
106
int longestSubarray(vector<int >& nums) {
105
107
int n = nums.size();
106
- vector<int > left(n);
107
- vector<int > right(n);
108
- for (int i = 1; i < n; ++i) {
109
- if (nums[ i - 1] == 1 ) {
108
+ vector<int > left(n + 1 );
109
+ vector<int > right(n + 1 );
110
+ for (int i = 1; i <= n; ++i) {
111
+ if (nums[ i - 1] ) {
110
112
left[ i] = left[ i - 1] + 1;
111
113
}
112
114
}
113
- for (int i = n - 2 ; ~ i; --i) {
114
- if (nums[ i + 1 ] == 1 ) {
115
+ for (int i = n - 1 ; ~ i; --i) {
116
+ if (nums[ i] ) {
115
117
right[ i] = right[ i + 1] + 1;
116
118
}
117
119
}
118
120
int ans = 0;
119
121
for (int i = 0; i < n; ++i) {
120
- ans = max(ans, left[ i] + right[ i] );
122
+ ans = max(ans, left[ i] + right[ i + 1 ] );
121
123
}
122
124
return ans;
123
125
}
124
126
};
125
127
```
126
128
127
129
```go
128
- func longestSubarray(nums []int) int {
130
+ func longestSubarray(nums []int) (ans int) {
129
131
n := len(nums)
130
- left := make([]int, n)
131
- right := make([]int, n)
132
- for i := 1; i < n; i++ {
132
+ left := make([]int, n+1 )
133
+ right := make([]int, n+1 )
134
+ for i := 1; i <= n; i++ {
133
135
if nums[i-1] == 1 {
134
136
left[i] = left[i-1] + 1
135
137
}
136
138
}
137
- for i := n - 2 ; i >= 0; i-- {
138
- if nums[i+1 ] == 1 {
139
+ for i := n - 1 ; i >= 0; i-- {
140
+ if nums[i] == 1 {
139
141
right[i] = right[i+1] + 1
140
142
}
141
143
}
142
- ans := 0
143
144
for i := 0; i < n; i++ {
144
- ans = max(ans, left[i]+right[i])
145
+ ans = max(ans, left[i]+right[i+1])
146
+ }
147
+ return
148
+ }
149
+ ```
150
+
151
+ ``` ts
152
+ function longestSubarray(nums : number []): number {
153
+ const n = nums .length ;
154
+ const left: number [] = Array (n + 1 ).fill (0 );
155
+ const right: number [] = Array (n + 1 ).fill (0 );
156
+ for (let i = 1 ; i <= n ; ++ i ) {
157
+ if (nums [i - 1 ]) {
158
+ left [i ] = left [i - 1 ] + 1 ;
159
+ }
160
+ }
161
+ for (let i = n - 1 ; ~ i ; -- i ) {
162
+ if (nums [i ]) {
163
+ right [i ] = right [i + 1 ] + 1 ;
164
+ }
165
+ }
166
+ let ans = 0 ;
167
+ for (let i = 0 ; i < n ; ++ i ) {
168
+ ans = Math .max (ans , left [i ] + right [i + 1 ]);
169
+ }
170
+ return ans ;
171
+ }
172
+ ```
173
+
174
+ <!-- tabs: end -->
175
+
176
+ ### 方法二:双指针
177
+
178
+ 题目实际上是让我们找出一个最长的子数组,该子数组中最多只包含一个 $0$,删掉该子数组中的其中一个元素后,剩余的长度即为答案。
179
+
180
+ 因此,我们可以用两个指针 $j$ 和 $i$ 分别指向子数组的左右边界,初始时 $j = 0$, $i = 0$。另外,我们用一个变量 $cnt$ 记录子数组中 $0$ 的个数。
181
+
182
+ 接下来,我们移动右指针 $i$,如果 $nums[ i] = 0$,则 $cnt$ 加 $1$。当 $cnt > 1$ 时,我们需要移动左指针 $j$,直到 $cnt \leq 1$。然后,我们更新答案,即 $ans = \max(ans, i - j)$。继续移动右指针 $i$,直到 $i$ 到达数组的末尾。
183
+
184
+ 时间复杂度 $O(n)$,其中 $n$ 为数组 $nums$ 的长度。空间复杂度 $O(1)$。
185
+
186
+ <!-- tabs: start -->
187
+
188
+ ``` python
189
+ class Solution :
190
+ def longestSubarray (self , nums : List[int ]) -> int :
191
+ ans = 0
192
+ cnt = j = 0
193
+ for i, x in enumerate (nums):
194
+ cnt += x ^ 1
195
+ while cnt > 1 :
196
+ cnt -= nums[j] ^ 1
197
+ j += 1
198
+ ans = max (ans, i - j)
199
+ return ans
200
+ ```
201
+
202
+ ``` java
203
+ class Solution {
204
+ public int longestSubarray (int [] nums ) {
205
+ int ans = 0 , n = nums. length;
206
+ for (int i = 0 , j = 0 , cnt = 0 ; i < n; ++ i) {
207
+ cnt += nums[i] ^ 1 ;
208
+ while (cnt > 1 ) {
209
+ cnt -= nums[j++ ] ^ 1 ;
210
+ }
211
+ ans = Math . max(ans, i - j);
212
+ }
213
+ return ans;
214
+ }
215
+ }
216
+ ```
217
+
218
+ ``` cpp
219
+ class Solution {
220
+ public:
221
+ int longestSubarray(vector<int >& nums) {
222
+ int ans = 0, n = nums.size();
223
+ for (int i = 0, j = 0, cnt = 0; i < n; ++i) {
224
+ cnt += nums[ i] ^ 1;
225
+ while (cnt > 1) {
226
+ cnt -= nums[ j++] ^ 1;
227
+ }
228
+ ans = max(ans, i - j);
229
+ }
230
+ return ans;
231
+ }
232
+ };
233
+ ```
234
+
235
+ ```go
236
+ func longestSubarray(nums []int) (ans int) {
237
+ cnt, j := 0, 0
238
+ for i, x := range nums {
239
+ cnt += x ^ 1
240
+ for ; cnt > 1; j++ {
241
+ cnt -= nums[j] ^ 1
242
+ }
243
+ ans = max(ans, i-j)
145
244
}
146
- return ans
245
+ return
246
+ }
247
+ ```
248
+
249
+ ``` ts
250
+ function longestSubarray(nums : number []): number {
251
+ let [ans, cnt, j] = [0 , 0 , 0 ];
252
+ for (let i = 0 ; i < nums .length ; ++ i ) {
253
+ cnt += nums [i ] ^ 1 ;
254
+ while (cnt > 1 ) {
255
+ cnt -= nums [j ++ ] ^ 1 ;
256
+ }
257
+ ans = Math .max (ans , i - j );
258
+ }
259
+ return ans ;
147
260
}
148
261
```
149
262
0 commit comments