Skip to content

Commit c2699ed

Browse files
authored
feat: add solutions to lc problems: No.1493,2730 (#2572)
* No.1493.Longest Subarray of 1's After Deleting One Element * No.2730.Find the Longest Semi-Repetitive Substring
1 parent c48370c commit c2699ed

File tree

19 files changed

+484
-225
lines changed

19 files changed

+484
-225
lines changed

solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md

+145-32
Original file line numberDiff line numberDiff line change
@@ -50,48 +50,50 @@
5050

5151
### 方法一:枚举
5252

53-
枚举删除的位置 $i$,那么每一个位置 $i$ 的最长子数组长度为 $i$ 左边连续的 $1$ 的个数加上 $i$ 右边连续的 $1$ 的个数。
53+
我们可以枚举每个删除的位置 $i$,然后计算左侧和右侧的连续 1 的个数,最后取最大值
5454

55-
因此,我们可以先遍历一遍数组,统计每个位置 $i$ 左边连续的 $1$ 的个数,记录在 `left` 数组;然后再从右向左遍历一遍数组,统计每个位置 $i$ 右边连续的 $1$ 的个数,记录在 `right` 数组,最后枚举删除的位置 $i$,求出最大值即可
55+
具体地,我们使用两个长度为 $n+1$ 的数组 $left$ 和 $right$,其中 $left[i]$ 表示以 $nums[i-1]$ 结尾的连续 $1$ 的个数,而 $right[i]$ 表示以 $nums[i]$ 开头的连续 $1$ 的个数
5656

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$ 的长度。
5860

5961
<!-- tabs:start -->
6062

6163
```python
6264
class Solution:
6365
def longestSubarray(self, nums: List[int]) -> int:
6466
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:
6971
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]:
7274
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))
7476
```
7577

7678
```java
7779
class Solution {
7880
public int longestSubarray(int[] nums) {
7981
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) {
8385
if (nums[i - 1] == 1) {
8486
left[i] = left[i - 1] + 1;
8587
}
8688
}
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) {
8991
right[i] = right[i + 1] + 1;
9092
}
9193
}
9294
int ans = 0;
9395
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]);
9597
}
9698
return ans;
9799
}
@@ -103,47 +105,158 @@ class Solution {
103105
public:
104106
int longestSubarray(vector<int>& nums) {
105107
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]) {
110112
left[i] = left[i - 1] + 1;
111113
}
112114
}
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]) {
115117
right[i] = right[i + 1] + 1;
116118
}
117119
}
118120
int ans = 0;
119121
for (int i = 0; i < n; ++i) {
120-
ans = max(ans, left[i] + right[i]);
122+
ans = max(ans, left[i] + right[i + 1]);
121123
}
122124
return ans;
123125
}
124126
};
125127
```
126128
127129
```go
128-
func longestSubarray(nums []int) int {
130+
func longestSubarray(nums []int) (ans int) {
129131
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++ {
133135
if nums[i-1] == 1 {
134136
left[i] = left[i-1] + 1
135137
}
136138
}
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 {
139141
right[i] = right[i+1] + 1
140142
}
141143
}
142-
ans := 0
143144
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)
145244
}
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;
147260
}
148261
```
149262

0 commit comments

Comments
 (0)