From c2699ed46ddec774cd1bf9d85d057af5ad9d8490 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Fri, 12 Apr 2024 08:55:05 +0800 Subject: [PATCH] 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 --- .../README.md | 177 +++++++++++++---- .../README_EN.md | 179 +++++++++++++++--- .../Solution.cpp | 14 +- .../Solution.go | 17 +- .../Solution.java | 12 +- .../Solution.py | 14 +- .../Solution.ts | 20 ++ .../Solution2.cpp | 14 ++ .../Solution2.go | 11 ++ .../Solution2.java | 13 ++ .../Solution2.py | 11 ++ .../Solution2.ts | 11 ++ .../README.md | 72 +++---- .../README_EN.md | 76 +++----- .../Solution.cpp | 16 +- .../Solution.go | 9 +- .../Solution.java | 16 +- .../Solution.py | 12 +- .../Solution.ts | 15 +- 19 files changed, 484 insertions(+), 225 deletions(-) create mode 100644 solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.ts create mode 100644 solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.cpp create mode 100644 solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.go create mode 100644 solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.java create mode 100644 solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.py create mode 100644 solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.ts diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md index 72e62fdf66eb0..e9ddcdd994bad 100644 --- a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md @@ -50,11 +50,13 @@ ### 方法一:枚举 -枚举删除的位置 $i$,那么每一个位置 $i$ 的最长子数组长度为 $i$ 左边连续的 $1$ 的个数加上 $i$ 右边连续的 $1$ 的个数。 +我们可以枚举每个删除的位置 $i$,然后计算左侧和右侧的连续 1 的个数,最后取最大值。 -因此,我们可以先遍历一遍数组,统计每个位置 $i$ 左边连续的 $1$ 的个数,记录在 `left` 数组;然后再从右向左遍历一遍数组,统计每个位置 $i$ 右边连续的 $1$ 的个数,记录在 `right` 数组,最后枚举删除的位置 $i$,求出最大值即可。 +具体地,我们使用两个长度为 $n+1$ 的数组 $left$ 和 $right$,其中 $left[i]$ 表示以 $nums[i-1]$ 结尾的连续 $1$ 的个数,而 $right[i]$ 表示以 $nums[i]$ 开头的连续 $1$ 的个数。 -时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。 +最终答案即为 $\max_{0 \leq i < n} \{left[i] + right[i+1]\}$。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。 @@ -62,36 +64,36 @@ class Solution: def longestSubarray(self, nums: List[int]) -> int: n = len(nums) - left = [0] * n - right = [0] * n - for i in range(1, n): - if nums[i - 1] == 1: + left = [0] * (n + 1) + right = [0] * (n + 1) + for i, x in enumerate(nums, 1): + if x: left[i] = left[i - 1] + 1 - for i in range(n - 2, -1, -1): - if nums[i + 1] == 1: + for i in range(n - 1, -1, -1): + if nums[i]: right[i] = right[i + 1] + 1 - return max(a + b for a, b in zip(left, right)) + return max(left[i] + right[i + 1] for i in range(n)) ``` ```java class Solution { public int longestSubarray(int[] nums) { int n = nums.length; - int[] left = new int[n]; - int[] right = new int[n]; - for (int i = 1; i < n; ++i) { + int[] left = new int[n + 1]; + int[] right = new int[n + 1]; + for (int i = 1; i <= n; ++i) { if (nums[i - 1] == 1) { left[i] = left[i - 1] + 1; } } - for (int i = n - 2; i >= 0; --i) { - if (nums[i + 1] == 1) { + for (int i = n - 1; i >= 0; --i) { + if (nums[i] == 1) { right[i] = right[i + 1] + 1; } } int ans = 0; for (int i = 0; i < n; ++i) { - ans = Math.max(ans, left[i] + right[i]); + ans = Math.max(ans, left[i] + right[i + 1]); } return ans; } @@ -103,21 +105,21 @@ class Solution { public: int longestSubarray(vector& nums) { int n = nums.size(); - vector left(n); - vector right(n); - for (int i = 1; i < n; ++i) { - if (nums[i - 1] == 1) { + vector left(n + 1); + vector right(n + 1); + for (int i = 1; i <= n; ++i) { + if (nums[i - 1]) { left[i] = left[i - 1] + 1; } } - for (int i = n - 2; ~i; --i) { - if (nums[i + 1] == 1) { + for (int i = n - 1; ~i; --i) { + if (nums[i]) { right[i] = right[i + 1] + 1; } } int ans = 0; for (int i = 0; i < n; ++i) { - ans = max(ans, left[i] + right[i]); + ans = max(ans, left[i] + right[i + 1]); } return ans; } @@ -125,25 +127,136 @@ public: ``` ```go -func longestSubarray(nums []int) int { +func longestSubarray(nums []int) (ans int) { n := len(nums) - left := make([]int, n) - right := make([]int, n) - for i := 1; i < n; i++ { + left := make([]int, n+1) + right := make([]int, n+1) + for i := 1; i <= n; i++ { if nums[i-1] == 1 { left[i] = left[i-1] + 1 } } - for i := n - 2; i >= 0; i-- { - if nums[i+1] == 1 { + for i := n - 1; i >= 0; i-- { + if nums[i] == 1 { right[i] = right[i+1] + 1 } } - ans := 0 for i := 0; i < n; i++ { - ans = max(ans, left[i]+right[i]) + ans = max(ans, left[i]+right[i+1]) + } + return +} +``` + +```ts +function longestSubarray(nums: number[]): number { + const n = nums.length; + const left: number[] = Array(n + 1).fill(0); + const right: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; ++i) { + if (nums[i - 1]) { + left[i] = left[i - 1] + 1; + } + } + for (let i = n - 1; ~i; --i) { + if (nums[i]) { + right[i] = right[i + 1] + 1; + } + } + let ans = 0; + for (let i = 0; i < n; ++i) { + ans = Math.max(ans, left[i] + right[i + 1]); + } + return ans; +} +``` + + + +### 方法二:双指针 + +题目实际上是让我们找出一个最长的子数组,该子数组中最多只包含一个 $0$,删掉该子数组中的其中一个元素后,剩余的长度即为答案。 + +因此,我们可以用两个指针 $j$ 和 $i$ 分别指向子数组的左右边界,初始时 $j = 0$, $i = 0$。另外,我们用一个变量 $cnt$ 记录子数组中 $0$ 的个数。 + +接下来,我们移动右指针 $i$,如果 $nums[i] = 0$,则 $cnt$ 加 $1$。当 $cnt > 1$ 时,我们需要移动左指针 $j$,直到 $cnt \leq 1$。然后,我们更新答案,即 $ans = \max(ans, i - j)$。继续移动右指针 $i$,直到 $i$ 到达数组的末尾。 + +时间复杂度 $O(n)$,其中 $n$ 为数组 $nums$ 的长度。空间复杂度 $O(1)$。 + + + +```python +class Solution: + def longestSubarray(self, nums: List[int]) -> int: + ans = 0 + cnt = j = 0 + for i, x in enumerate(nums): + cnt += x ^ 1 + while cnt > 1: + cnt -= nums[j] ^ 1 + j += 1 + ans = max(ans, i - j) + return ans +``` + +```java +class Solution { + public int longestSubarray(int[] nums) { + int ans = 0, n = nums.length; + for (int i = 0, j = 0, cnt = 0; i < n; ++i) { + cnt += nums[i] ^ 1; + while (cnt > 1) { + cnt -= nums[j++] ^ 1; + } + ans = Math.max(ans, i - j); + } + return ans; + } +} +``` + +```cpp +class Solution { +public: + int longestSubarray(vector& nums) { + int ans = 0, n = nums.size(); + for (int i = 0, j = 0, cnt = 0; i < n; ++i) { + cnt += nums[i] ^ 1; + while (cnt > 1) { + cnt -= nums[j++] ^ 1; + } + ans = max(ans, i - j); + } + return ans; + } +}; +``` + +```go +func longestSubarray(nums []int) (ans int) { + cnt, j := 0, 0 + for i, x := range nums { + cnt += x ^ 1 + for ; cnt > 1; j++ { + cnt -= nums[j] ^ 1 + } + ans = max(ans, i-j) } - return ans + return +} +``` + +```ts +function longestSubarray(nums: number[]): number { + let [ans, cnt, j] = [0, 0, 0]; + for (let i = 0; i < nums.length; ++i) { + cnt += nums[i] ^ 1; + while (cnt > 1) { + cnt -= nums[j++] ^ 1; + } + ans = Math.max(ans, i - j); + } + return ans; } ``` diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README_EN.md b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README_EN.md index 98db5fb4d7dbc..9a4bc24c226f2 100644 --- a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README_EN.md +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README_EN.md @@ -45,7 +45,15 @@ ## Solutions -### Solution 1 +### Solution 1: Enumeration + +We can enumerate each position $i$ to be deleted, then calculate the number of consecutive 1s on the left and right, and finally take the maximum value. + +Specifically, we use two arrays $left$ and $right$ of length $n+1$, where $left[i]$ represents the number of consecutive 1s ending with $nums[i-1]$, and $right[i]$ represents the number of consecutive 1s starting with $nums[i]$. + +The final answer is $\max_{0 \leq i < n} \{left[i] + right[i+1]\}$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array $nums$. @@ -53,36 +61,36 @@ class Solution: def longestSubarray(self, nums: List[int]) -> int: n = len(nums) - left = [0] * n - right = [0] * n - for i in range(1, n): - if nums[i - 1] == 1: + left = [0] * (n + 1) + right = [0] * (n + 1) + for i, x in enumerate(nums, 1): + if x: left[i] = left[i - 1] + 1 - for i in range(n - 2, -1, -1): - if nums[i + 1] == 1: + for i in range(n - 1, -1, -1): + if nums[i]: right[i] = right[i + 1] + 1 - return max(a + b for a, b in zip(left, right)) + return max(left[i] + right[i + 1] for i in range(n)) ``` ```java class Solution { public int longestSubarray(int[] nums) { int n = nums.length; - int[] left = new int[n]; - int[] right = new int[n]; - for (int i = 1; i < n; ++i) { + int[] left = new int[n + 1]; + int[] right = new int[n + 1]; + for (int i = 1; i <= n; ++i) { if (nums[i - 1] == 1) { left[i] = left[i - 1] + 1; } } - for (int i = n - 2; i >= 0; --i) { - if (nums[i + 1] == 1) { + for (int i = n - 1; i >= 0; --i) { + if (nums[i] == 1) { right[i] = right[i + 1] + 1; } } int ans = 0; for (int i = 0; i < n; ++i) { - ans = Math.max(ans, left[i] + right[i]); + ans = Math.max(ans, left[i] + right[i + 1]); } return ans; } @@ -94,21 +102,21 @@ class Solution { public: int longestSubarray(vector& nums) { int n = nums.size(); - vector left(n); - vector right(n); - for (int i = 1; i < n; ++i) { - if (nums[i - 1] == 1) { + vector left(n + 1); + vector right(n + 1); + for (int i = 1; i <= n; ++i) { + if (nums[i - 1]) { left[i] = left[i - 1] + 1; } } - for (int i = n - 2; ~i; --i) { - if (nums[i + 1] == 1) { + for (int i = n - 1; ~i; --i) { + if (nums[i]) { right[i] = right[i + 1] + 1; } } int ans = 0; for (int i = 0; i < n; ++i) { - ans = max(ans, left[i] + right[i]); + ans = max(ans, left[i] + right[i + 1]); } return ans; } @@ -116,25 +124,136 @@ public: ``` ```go -func longestSubarray(nums []int) int { +func longestSubarray(nums []int) (ans int) { n := len(nums) - left := make([]int, n) - right := make([]int, n) - for i := 1; i < n; i++ { + left := make([]int, n+1) + right := make([]int, n+1) + for i := 1; i <= n; i++ { if nums[i-1] == 1 { left[i] = left[i-1] + 1 } } - for i := n - 2; i >= 0; i-- { - if nums[i+1] == 1 { + for i := n - 1; i >= 0; i-- { + if nums[i] == 1 { right[i] = right[i+1] + 1 } } - ans := 0 for i := 0; i < n; i++ { - ans = max(ans, left[i]+right[i]) + ans = max(ans, left[i]+right[i+1]) } - return ans + return +} +``` + +```ts +function longestSubarray(nums: number[]): number { + const n = nums.length; + const left: number[] = Array(n + 1).fill(0); + const right: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; ++i) { + if (nums[i - 1]) { + left[i] = left[i - 1] + 1; + } + } + for (let i = n - 1; ~i; --i) { + if (nums[i]) { + right[i] = right[i + 1] + 1; + } + } + let ans = 0; + for (let i = 0; i < n; ++i) { + ans = Math.max(ans, left[i] + right[i + 1]); + } + return ans; +} +``` + + + +### Solution 2: Two Pointers + +The problem is actually asking us to find the longest subarray that contains at most one $0$. The remaining length after deleting one element from this subarray is the answer. + +Therefore, we can use two pointers $j$ and $i$ to point to the left and right boundaries of the subarray, initially $j = 0$, $i = 0$. In addition, we use a variable $cnt$ to record the number of $0$s in the subarray. + +Next, we move the right pointer $i$. If $nums[i] = 0$, then $cnt$ is incremented by $1$. When $cnt > 1$, we need to move the left pointer $j$ until $cnt \leq 1$. Then, we update the answer, i.e., $ans = \max(ans, i - j)$. Continue to move the right pointer $i$ until $i$ reaches the end of the array. + +The time complexity is $O(n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$. + + + +```python +class Solution: + def longestSubarray(self, nums: List[int]) -> int: + ans = 0 + cnt = j = 0 + for i, x in enumerate(nums): + cnt += x ^ 1 + while cnt > 1: + cnt -= nums[j] ^ 1 + j += 1 + ans = max(ans, i - j) + return ans +``` + +```java +class Solution { + public int longestSubarray(int[] nums) { + int ans = 0, n = nums.length; + for (int i = 0, j = 0, cnt = 0; i < n; ++i) { + cnt += nums[i] ^ 1; + while (cnt > 1) { + cnt -= nums[j++] ^ 1; + } + ans = Math.max(ans, i - j); + } + return ans; + } +} +``` + +```cpp +class Solution { +public: + int longestSubarray(vector& nums) { + int ans = 0, n = nums.size(); + for (int i = 0, j = 0, cnt = 0; i < n; ++i) { + cnt += nums[i] ^ 1; + while (cnt > 1) { + cnt -= nums[j++] ^ 1; + } + ans = max(ans, i - j); + } + return ans; + } +}; +``` + +```go +func longestSubarray(nums []int) (ans int) { + cnt, j := 0, 0 + for i, x := range nums { + cnt += x ^ 1 + for ; cnt > 1; j++ { + cnt -= nums[j] ^ 1 + } + ans = max(ans, i-j) + } + return +} +``` + +```ts +function longestSubarray(nums: number[]): number { + let [ans, cnt, j] = [0, 0, 0]; + for (let i = 0; i < nums.length; ++i) { + cnt += nums[i] ^ 1; + while (cnt > 1) { + cnt -= nums[j++] ^ 1; + } + ans = Math.max(ans, i - j); + } + return ans; } ``` diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.cpp b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.cpp index 3ac30265e7289..276f61bf3a6f4 100644 --- a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.cpp +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.cpp @@ -2,21 +2,21 @@ class Solution { public: int longestSubarray(vector& nums) { int n = nums.size(); - vector left(n); - vector right(n); - for (int i = 1; i < n; ++i) { - if (nums[i - 1] == 1) { + vector left(n + 1); + vector right(n + 1); + for (int i = 1; i <= n; ++i) { + if (nums[i - 1]) { left[i] = left[i - 1] + 1; } } - for (int i = n - 2; ~i; --i) { - if (nums[i + 1] == 1) { + for (int i = n - 1; ~i; --i) { + if (nums[i]) { right[i] = right[i + 1] + 1; } } int ans = 0; for (int i = 0; i < n; ++i) { - ans = max(ans, left[i] + right[i]); + ans = max(ans, left[i] + right[i + 1]); } return ans; } diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.go b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.go index 663ab986753fa..b5bb3ebbb6f13 100644 --- a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.go +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.go @@ -1,20 +1,19 @@ -func longestSubarray(nums []int) int { +func longestSubarray(nums []int) (ans int) { n := len(nums) - left := make([]int, n) - right := make([]int, n) - for i := 1; i < n; i++ { + left := make([]int, n+1) + right := make([]int, n+1) + for i := 1; i <= n; i++ { if nums[i-1] == 1 { left[i] = left[i-1] + 1 } } - for i := n - 2; i >= 0; i-- { - if nums[i+1] == 1 { + for i := n - 1; i >= 0; i-- { + if nums[i] == 1 { right[i] = right[i+1] + 1 } } - ans := 0 for i := 0; i < n; i++ { - ans = max(ans, left[i]+right[i]) + ans = max(ans, left[i]+right[i+1]) } - return ans + return } \ No newline at end of file diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.java b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.java index 900dfc79cbb53..15508875bf078 100644 --- a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.java +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.java @@ -1,21 +1,21 @@ class Solution { public int longestSubarray(int[] nums) { int n = nums.length; - int[] left = new int[n]; - int[] right = new int[n]; - for (int i = 1; i < n; ++i) { + int[] left = new int[n + 1]; + int[] right = new int[n + 1]; + for (int i = 1; i <= n; ++i) { if (nums[i - 1] == 1) { left[i] = left[i - 1] + 1; } } - for (int i = n - 2; i >= 0; --i) { - if (nums[i + 1] == 1) { + for (int i = n - 1; i >= 0; --i) { + if (nums[i] == 1) { right[i] = right[i + 1] + 1; } } int ans = 0; for (int i = 0; i < n; ++i) { - ans = Math.max(ans, left[i] + right[i]); + ans = Math.max(ans, left[i] + right[i + 1]); } return ans; } diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.py b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.py index d7b85a525f8f8..0c21888310de4 100644 --- a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.py +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.py @@ -1,12 +1,12 @@ class Solution: def longestSubarray(self, nums: List[int]) -> int: n = len(nums) - left = [0] * n - right = [0] * n - for i in range(1, n): - if nums[i - 1] == 1: + left = [0] * (n + 1) + right = [0] * (n + 1) + for i, x in enumerate(nums, 1): + if x: left[i] = left[i - 1] + 1 - for i in range(n - 2, -1, -1): - if nums[i + 1] == 1: + for i in range(n - 1, -1, -1): + if nums[i]: right[i] = right[i + 1] + 1 - return max(a + b for a, b in zip(left, right)) + return max(left[i] + right[i + 1] for i in range(n)) diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.ts b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.ts new file mode 100644 index 0000000000000..ac50d8bca4fb2 --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.ts @@ -0,0 +1,20 @@ +function longestSubarray(nums: number[]): number { + const n = nums.length; + const left: number[] = Array(n + 1).fill(0); + const right: number[] = Array(n + 1).fill(0); + for (let i = 1; i <= n; ++i) { + if (nums[i - 1]) { + left[i] = left[i - 1] + 1; + } + } + for (let i = n - 1; ~i; --i) { + if (nums[i]) { + right[i] = right[i + 1] + 1; + } + } + let ans = 0; + for (let i = 0; i < n; ++i) { + ans = Math.max(ans, left[i] + right[i + 1]); + } + return ans; +} diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.cpp b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.cpp new file mode 100644 index 0000000000000..018a815bea3bc --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.cpp @@ -0,0 +1,14 @@ +class Solution { +public: + int longestSubarray(vector& nums) { + int ans = 0, n = nums.size(); + for (int i = 0, j = 0, cnt = 0; i < n; ++i) { + cnt += nums[i] ^ 1; + while (cnt > 1) { + cnt -= nums[j++] ^ 1; + } + ans = max(ans, i - j); + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.go b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.go new file mode 100644 index 0000000000000..d178b8710aa92 --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.go @@ -0,0 +1,11 @@ +func longestSubarray(nums []int) (ans int) { + cnt, j := 0, 0 + for i, x := range nums { + cnt += x ^ 1 + for ; cnt > 1; j++ { + cnt -= nums[j] ^ 1 + } + ans = max(ans, i-j) + } + return +} \ No newline at end of file diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.java b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.java new file mode 100644 index 0000000000000..7ad9a58457e56 --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.java @@ -0,0 +1,13 @@ +class Solution { + public int longestSubarray(int[] nums) { + int ans = 0, n = nums.length; + for (int i = 0, j = 0, cnt = 0; i < n; ++i) { + cnt += nums[i] ^ 1; + while (cnt > 1) { + cnt -= nums[j++] ^ 1; + } + ans = Math.max(ans, i - j); + } + return ans; + } +} \ No newline at end of file diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.py b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.py new file mode 100644 index 0000000000000..f0c0a0985d3de --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.py @@ -0,0 +1,11 @@ +class Solution: + def longestSubarray(self, nums: List[int]) -> int: + ans = 0 + cnt = j = 0 + for i, x in enumerate(nums): + cnt += x ^ 1 + while cnt > 1: + cnt -= nums[j] ^ 1 + j += 1 + ans = max(ans, i - j) + return ans diff --git a/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.ts b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.ts new file mode 100644 index 0000000000000..65318c5f1a629 --- /dev/null +++ b/solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution2.ts @@ -0,0 +1,11 @@ +function longestSubarray(nums: number[]): number { + let [ans, cnt, j] = [0, 0, 0]; + for (let i = 0; i < nums.length; ++i) { + cnt += nums[i] ^ 1; + while (cnt > 1) { + cnt -= nums[j++] ^ 1; + } + ans = Math.max(ans, i - j); + } + return ans; +} diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README.md b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README.md index de7c7dd2e86f6..7fcf2a0b2d77e 100644 --- a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README.md +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README.md @@ -55,7 +55,9 @@ ### 方法一:双指针 -我们用双指针维护一个区间 $s[j..i]$,使得区间内最多只有一个相邻字符相等。我们用 $cnt$ 记录区间内相邻字符相等的个数,如果 $cnt \gt 1$,那么我们就需要移动左指针 $j$,直到 $cnt \le 1$。每一次,我们更新答案为 $ans = \max(ans, i - j + 1)$。 +我们用双指针维护一个区间 $s[j..i]$,使得区间内最多只有一个相邻字符相等,初始时 $j = 0$, $i = 1$。初始化答案 $ans = 1$。 + +我们用 $cnt$ 记录区间内相邻字符相等的个数,如果 $cnt \gt 1$,那么我们就需要移动左指针 $j$,直到 $cnt \le 1$。每一次,我们更新答案为 $ans = \max(ans, i - j + 1)$。 时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度 $O(1)$。 @@ -64,14 +66,12 @@ ```python class Solution: def longestSemiRepetitiveSubstring(self, s: str) -> int: - n = len(s) - ans = cnt = j = 0 - for i in range(n): - if i and s[i] == s[i - 1]: - cnt += 1 + ans, n = 1, len(s) + cnt = j = 0 + for i in range(1, n): + cnt += s[i] == s[i - 1] while cnt > 1: - if s[j] == s[j + 1]: - cnt -= 1 + cnt -= s[j] == s[j + 1] j += 1 ans = max(ans, i - j + 1) return ans @@ -80,17 +80,11 @@ class Solution: ```java class Solution { public int longestSemiRepetitiveSubstring(String s) { - int n = s.length(); - int ans = 0; - for (int i = 0, j = 0, cnt = 0; i < n; ++i) { - if (i > 0 && s.charAt(i) == s.charAt(i - 1)) { - ++cnt; - } - while (cnt > 1) { - if (s.charAt(j) == s.charAt(j + 1)) { - --cnt; - } - ++j; + int ans = 1, n = s.length(); + for (int i = 1, j = 0, cnt = 0; i < n; ++i) { + cnt += s.charAt(i) == s.charAt(i - 1) ? 1 : 0; + for (; cnt > 1; ++j) { + cnt -= s.charAt(j) == s.charAt(j + 1) ? 1 : 0; } ans = Math.max(ans, i - j + 1); } @@ -103,17 +97,11 @@ class Solution { class Solution { public: int longestSemiRepetitiveSubstring(string s) { - int n = s.size(); - int ans = 0; - for (int i = 0, j = 0, cnt = 0; i < n; ++i) { - if (i && s[i] == s[i - 1]) { - ++cnt; - } - while (cnt > 1) { - if (s[j] == s[j + 1]) { - --cnt; - } - ++j; + int ans = 1, n = s.size(); + for (int i = 1, j = 0, cnt = 0; i < n; ++i) { + cnt += s[i] == s[i - 1] ? 1 : 0; + for (; cnt > 1; ++j) { + cnt -= s[j] == s[j + 1] ? 1 : 0; } ans = max(ans, i - j + 1); } @@ -124,16 +112,15 @@ public: ```go func longestSemiRepetitiveSubstring(s string) (ans int) { - n := len(s) - for i, j, cnt := 0, 0, 0; i < n; i++ { - if i > 0 && s[i] == s[i-1] { + ans = 1 + for i, j, cnt := 1, 0, 0; i < len(s); i++ { + if s[i] == s[i-1] { cnt++ } - for cnt > 1 { + for ; cnt > 1; j++ { if s[j] == s[j+1] { cnt-- } - j++ } ans = max(ans, i-j+1) } @@ -144,16 +131,11 @@ func longestSemiRepetitiveSubstring(s string) (ans int) { ```ts function longestSemiRepetitiveSubstring(s: string): number { const n = s.length; - let ans = 0; - for (let i = 0, j = 0, cnt = 0; i < n; ++i) { - if (i > 0 && s[i] === s[i - 1]) { - ++cnt; - } - while (cnt > 1) { - if (s[j] === s[j + 1]) { - --cnt; - } - ++j; + let ans = 1; + for (let i = 1, j = 0, cnt = 0; i < n; ++i) { + cnt += s[i] === s[i - 1] ? 1 : 0; + for (; cnt > 1; ++j) { + cnt -= s[j] === s[j + 1] ? 1 : 0; } ans = Math.max(ans, i - j + 1); } diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README_EN.md b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README_EN.md index b018272985d76..3fb3f8a09bf70 100644 --- a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README_EN.md +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/README_EN.md @@ -49,21 +49,25 @@ ## Solutions -### Solution 1 +### Solution 1: Two Pointers + +We use two pointers to maintain a range $s[j..i]$ such that there is at most one pair of adjacent characters that are equal, initially $j = 0$, $i = 1$. Initialize the answer $ans = 1$. + +We use $cnt$ to record the number of pairs of adjacent characters that are equal in the range. If $cnt > 1$, then we need to move the left pointer $j$ until $cnt \le 1$. Each time, we update the answer as $ans = \max(ans, i - j + 1)$. + +The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(1)$. ```python class Solution: def longestSemiRepetitiveSubstring(self, s: str) -> int: - n = len(s) - ans = cnt = j = 0 - for i in range(n): - if i and s[i] == s[i - 1]: - cnt += 1 + ans, n = 1, len(s) + cnt = j = 0 + for i in range(1, n): + cnt += s[i] == s[i - 1] while cnt > 1: - if s[j] == s[j + 1]: - cnt -= 1 + cnt -= s[j] == s[j + 1] j += 1 ans = max(ans, i - j + 1) return ans @@ -72,17 +76,11 @@ class Solution: ```java class Solution { public int longestSemiRepetitiveSubstring(String s) { - int n = s.length(); - int ans = 0; - for (int i = 0, j = 0, cnt = 0; i < n; ++i) { - if (i > 0 && s.charAt(i) == s.charAt(i - 1)) { - ++cnt; - } - while (cnt > 1) { - if (s.charAt(j) == s.charAt(j + 1)) { - --cnt; - } - ++j; + int ans = 1, n = s.length(); + for (int i = 1, j = 0, cnt = 0; i < n; ++i) { + cnt += s.charAt(i) == s.charAt(i - 1) ? 1 : 0; + for (; cnt > 1; ++j) { + cnt -= s.charAt(j) == s.charAt(j + 1) ? 1 : 0; } ans = Math.max(ans, i - j + 1); } @@ -95,17 +93,11 @@ class Solution { class Solution { public: int longestSemiRepetitiveSubstring(string s) { - int n = s.size(); - int ans = 0; - for (int i = 0, j = 0, cnt = 0; i < n; ++i) { - if (i && s[i] == s[i - 1]) { - ++cnt; - } - while (cnt > 1) { - if (s[j] == s[j + 1]) { - --cnt; - } - ++j; + int ans = 1, n = s.size(); + for (int i = 1, j = 0, cnt = 0; i < n; ++i) { + cnt += s[i] == s[i - 1] ? 1 : 0; + for (; cnt > 1; ++j) { + cnt -= s[j] == s[j + 1] ? 1 : 0; } ans = max(ans, i - j + 1); } @@ -116,16 +108,15 @@ public: ```go func longestSemiRepetitiveSubstring(s string) (ans int) { - n := len(s) - for i, j, cnt := 0, 0, 0; i < n; i++ { - if i > 0 && s[i] == s[i-1] { + ans = 1 + for i, j, cnt := 1, 0, 0; i < len(s); i++ { + if s[i] == s[i-1] { cnt++ } - for cnt > 1 { + for ; cnt > 1; j++ { if s[j] == s[j+1] { cnt-- } - j++ } ans = max(ans, i-j+1) } @@ -136,16 +127,11 @@ func longestSemiRepetitiveSubstring(s string) (ans int) { ```ts function longestSemiRepetitiveSubstring(s: string): number { const n = s.length; - let ans = 0; - for (let i = 0, j = 0, cnt = 0; i < n; ++i) { - if (i > 0 && s[i] === s[i - 1]) { - ++cnt; - } - while (cnt > 1) { - if (s[j] === s[j + 1]) { - --cnt; - } - ++j; + let ans = 1; + for (let i = 1, j = 0, cnt = 0; i < n; ++i) { + cnt += s[i] === s[i - 1] ? 1 : 0; + for (; cnt > 1; ++j) { + cnt -= s[j] === s[j + 1] ? 1 : 0; } ans = Math.max(ans, i - j + 1); } diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.cpp b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.cpp index 3646a7bdd2a9e..92eb86a8ccace 100644 --- a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.cpp +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.cpp @@ -1,17 +1,11 @@ class Solution { public: int longestSemiRepetitiveSubstring(string s) { - int n = s.size(); - int ans = 0; - for (int i = 0, j = 0, cnt = 0; i < n; ++i) { - if (i && s[i] == s[i - 1]) { - ++cnt; - } - while (cnt > 1) { - if (s[j] == s[j + 1]) { - --cnt; - } - ++j; + int ans = 1, n = s.size(); + for (int i = 1, j = 0, cnt = 0; i < n; ++i) { + cnt += s[i] == s[i - 1] ? 1 : 0; + for (; cnt > 1; ++j) { + cnt -= s[j] == s[j + 1] ? 1 : 0; } ans = max(ans, i - j + 1); } diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.go b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.go index e214574eb34bd..e642207528967 100644 --- a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.go +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.go @@ -1,14 +1,13 @@ func longestSemiRepetitiveSubstring(s string) (ans int) { - n := len(s) - for i, j, cnt := 0, 0, 0; i < n; i++ { - if i > 0 && s[i] == s[i-1] { + ans = 1 + for i, j, cnt := 1, 0, 0; i < len(s); i++ { + if s[i] == s[i-1] { cnt++ } - for cnt > 1 { + for ; cnt > 1; j++ { if s[j] == s[j+1] { cnt-- } - j++ } ans = max(ans, i-j+1) } diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.java b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.java index 8c186ef9220cf..a8ce6e1ed9c96 100644 --- a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.java +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.java @@ -1,16 +1,10 @@ class Solution { public int longestSemiRepetitiveSubstring(String s) { - int n = s.length(); - int ans = 0; - for (int i = 0, j = 0, cnt = 0; i < n; ++i) { - if (i > 0 && s.charAt(i) == s.charAt(i - 1)) { - ++cnt; - } - while (cnt > 1) { - if (s.charAt(j) == s.charAt(j + 1)) { - --cnt; - } - ++j; + int ans = 1, n = s.length(); + for (int i = 1, j = 0, cnt = 0; i < n; ++i) { + cnt += s.charAt(i) == s.charAt(i - 1) ? 1 : 0; + for (; cnt > 1; ++j) { + cnt -= s.charAt(j) == s.charAt(j + 1) ? 1 : 0; } ans = Math.max(ans, i - j + 1); } diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.py b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.py index 3709f1ba7fe27..0af425eb61672 100644 --- a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.py +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.py @@ -1,13 +1,11 @@ class Solution: def longestSemiRepetitiveSubstring(self, s: str) -> int: - n = len(s) - ans = cnt = j = 0 - for i in range(n): - if i and s[i] == s[i - 1]: - cnt += 1 + ans, n = 1, len(s) + cnt = j = 0 + for i in range(1, n): + cnt += s[i] == s[i - 1] while cnt > 1: - if s[j] == s[j + 1]: - cnt -= 1 + cnt -= s[j] == s[j + 1] j += 1 ans = max(ans, i - j + 1) return ans diff --git a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.ts b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.ts index 53b5252cac0d0..297579a44a8cf 100644 --- a/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.ts +++ b/solution/2700-2799/2730.Find the Longest Semi-Repetitive Substring/Solution.ts @@ -1,15 +1,10 @@ function longestSemiRepetitiveSubstring(s: string): number { const n = s.length; - let ans = 0; - for (let i = 0, j = 0, cnt = 0; i < n; ++i) { - if (i > 0 && s[i] === s[i - 1]) { - ++cnt; - } - while (cnt > 1) { - if (s[j] === s[j + 1]) { - --cnt; - } - ++j; + let ans = 1; + for (let i = 1, j = 0, cnt = 0; i < n; ++i) { + cnt += s[i] === s[i - 1] ? 1 : 0; + for (; cnt > 1; ++j) { + cnt -= s[j] === s[j + 1] ? 1 : 0; } ans = Math.max(ans, i - j + 1); }