Skip to content

Commit f5a275d

Browse files
authored
feat: update solutions to lc problem: No.2401 (doocs#3520)
No.2401.Longest Nice Subarray
1 parent 599ad45 commit f5a275d

File tree

9 files changed

+131
-154
lines changed

9 files changed

+131
-154
lines changed

solution/2400-2499/2401.Longest Nice Subarray/README.md

+44-53
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,15 @@ tags:
6666

6767
### 方法一:双指针
6868

69-
我们定义一个变量 $mask$,用于记录当前子数组中的元素按位或的结果,初始时 $mask = 0$。另外,使用双指针 $j$ 和 $i$ 分别指向当前子数组的左右端点,初始时 $i = j = 0$。
69+
根据题目描述,子数组的每个元素的二进制位上的 $1$ 的位置不能相同,这样才能保证任意两个元素的按位与结果为 $0$。
7070

71-
接下来,我们从左到右遍历数组 $nums$,对于遍历到的每个元素 $x$:
71+
因此,我们可以使用双指针 $l$ 和 $r$ 维护一个滑动窗口,使得窗口内的元素满足题目条件。
7272

73-
我们将其与 $mask$ 按位与,如果结果不为 $0$,则说明 $x$ 和 $mask$ 中至少有一个元素的二进制表示中的某一位为 $1$,而另一个元素的二进制表示中的对应位为 $0$,这样的元素对不可能满足题目要求,因此我们需要将 $j$ 右移,直到 $x$ 和 $mask$ 按位与的结果为 $0$ 为止
73+
我们用一个变量 $\textit{mask}$ 来表示窗口内的元素的按位或的结果,接下来,遍历数组的每个元素。对于当前元素 $x$,如果 $\textit{mask}$ 和 $x$ 的按位与结果不为 $0$,说明当前元素 $x$ 与窗口内的元素有重复的二进制位,此时需要移动左指针 $l$,直到 $\textit{mask}$ 和 $x$ 的按位与结果为 $0$。然后,我们将 $\textit{mask}$ 和 $x$ 的按位或的结果赋值给 $\textit{mask}$,并更新答案 $\textit{ans} = \max(\textit{ans}, r - l + 1)$
7474

75-
此时,我们就找到了一个满足题目要求的子数组,其长度为 $i - j + 1$,我们将其与当前的最长优雅子数组的长度进行比较,如果大于当前的最长优雅子数组的长度,则更新最长优雅子数组的长度
75+
遍历结束后,返回答案 $\textit{ans}$ 即可
7676

77-
然后我们将 $mask$ 和 $x$ 按位或,继续遍历下一个元素。
78-
79-
最终,我们得到的最长优雅子数组的长度即为答案。
80-
81-
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $nums$ 的长度。
77+
时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{nums}$ 的长度。空间复杂度 $O(1)$。
8278

8379
<!-- tabs:start -->
8480

@@ -87,13 +83,13 @@ tags:
8783
```python
8884
class Solution:
8985
def longestNiceSubarray(self, nums: List[int]) -> int:
90-
ans = j = mask = 0
91-
for i, x in enumerate(nums):
86+
ans = mask = l = 0
87+
for r, x in enumerate(nums):
9288
while mask & x:
93-
mask ^= nums[j]
94-
j += 1
95-
ans = max(ans, i - j + 1)
89+
mask ^= nums[l]
90+
l += 1
9691
mask |= x
92+
ans = max(ans, r - l + 1)
9793
return ans
9894
```
9995

@@ -103,12 +99,12 @@ class Solution:
10399
class Solution {
104100
public int longestNiceSubarray(int[] nums) {
105101
int ans = 0, mask = 0;
106-
for (int i = 0, j = 0; i < nums.length; ++i) {
107-
while ((mask & nums[i]) != 0) {
108-
mask ^= nums[j++];
102+
for (int l = 0, r = 0; r < nums.length; ++r) {
103+
while ((mask & nums[r]) != 0) {
104+
mask ^= nums[l++];
109105
}
110-
ans = Math.max(ans, i - j + 1);
111-
mask |= nums[i];
106+
mask |= nums[r];
107+
ans = Math.max(ans, r - l + 1);
112108
}
113109
return ans;
114110
}
@@ -122,12 +118,12 @@ class Solution {
122118
public:
123119
int longestNiceSubarray(vector<int>& nums) {
124120
int ans = 0, mask = 0;
125-
for (int i = 0, j = 0; i < nums.size(); ++i) {
126-
while (mask & nums[i]) {
127-
mask ^= nums[j++];
121+
for (int l = 0, r = 0; r < nums.size(); ++r) {
122+
while (mask & nums[r]) {
123+
mask ^= nums[l++];
128124
}
129-
ans = max(ans, i - j + 1);
130-
mask |= nums[i];
125+
mask |= nums[r];
126+
ans = max(ans, r - l + 1);
131127
}
132128
return ans;
133129
}
@@ -138,15 +134,14 @@ public:
138134
139135
```go
140136
func longestNiceSubarray(nums []int) (ans int) {
141-
mask, j := 0, 0
142-
for i, x := range nums {
143-
for ; mask&x != 0; j++ {
144-
mask ^= nums[j]
145-
}
146-
if k := i - j + 1; ans < k {
147-
ans = k
137+
mask, l := 0, 0
138+
for r, x := range nums {
139+
for mask&x != 0 {
140+
mask ^= nums[l]
141+
l++
148142
}
149143
mask |= x
144+
ans = max(ans, r-l+1)
150145
}
151146
return
152147
}
@@ -156,14 +151,13 @@ func longestNiceSubarray(nums []int) (ans int) {
156151

157152
```ts
158153
function longestNiceSubarray(nums: number[]): number {
159-
let mask = 0;
160-
let ans = 0;
161-
for (let i = 0, j = 0; i < nums.length; ++i) {
162-
while ((mask & nums[i]) !== 0) {
163-
mask ^= nums[j++];
154+
let [ans, mask] = [0, 0];
155+
for (let l = 0, r = 0; r < nums.length; ++r) {
156+
while (mask & nums[r]) {
157+
mask ^= nums[l++];
164158
}
165-
ans = Math.max(ans, i - j + 1);
166-
mask |= nums[i];
159+
mask |= nums[r];
160+
ans = Math.max(ans, r - l + 1);
167161
}
168162
return ans;
169163
}
@@ -176,19 +170,16 @@ impl Solution {
176170
pub fn longest_nice_subarray(nums: Vec<i32>) -> i32 {
177171
let mut ans = 0;
178172
let mut mask = 0;
179-
let mut j = 0;
180-
181-
for (i, &x) in nums.iter().enumerate() {
182-
let mut x = x;
183-
while (mask & x) != 0 {
184-
mask ^= nums[j];
185-
j += 1;
173+
let mut l = 0;
174+
for (r, &x) in nums.iter().enumerate() {
175+
while mask & x != 0 {
176+
mask ^= nums[l];
177+
l += 1;
186178
}
187-
ans = ans.max(i - j + 1);
188179
mask |= x;
180+
ans = ans.max((r - l + 1) as i32);
189181
}
190-
191-
ans as i32
182+
ans
192183
}
193184
}
194185
```
@@ -199,12 +190,12 @@ impl Solution {
199190
public class Solution {
200191
public int LongestNiceSubarray(int[] nums) {
201192
int ans = 0, mask = 0;
202-
for (int i = 0, j = 0; i < nums.Length; ++i) {
203-
while ((mask & nums[i]) != 0) {
204-
mask ^= nums[j++];
193+
for (int l = 0, r = 0; r < nums.Length; ++r) {
194+
while ((mask & nums[r]) != 0) {
195+
mask ^= nums[l++];
205196
}
206-
ans = Math.Max(ans, i - j + 1);
207-
mask |= nums[i];
197+
mask |= nums[r];
198+
ans = Math.Max(ans, r - l + 1);
208199
}
209200
return ans;
210201
}

solution/2400-2499/2401.Longest Nice Subarray/README_EN.md

+44-53
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,15 @@ It can be proven that no longer nice subarray can be obtained, so we return 3.</
6666

6767
### Solution 1: Two Pointers
6868

69-
We define a variable $mask$ to record the bitwise OR result of the elements in the current subarray, initially $mask = 0$. Also, we use two pointers $j$ and $i$ to point to the left and right endpoints of the current subarray, initially $i = j = 0$.
69+
According to the problem description, the position of the binary $1$ in each element of the subarray must be unique to ensure that the bitwise AND result of any two elements is $0$.
7070

71-
Next, we traverse the array $nums$ from left to right. For each element $x$ we encounter:
71+
Therefore, we can use two pointers, $l$ and $r$, to maintain a sliding window such that the elements within the window satisfy the problem's conditions.
7272

73-
We perform a bitwise AND operation between it and $mask$. If the result is not $0$, it means that $x$ and at least one element in $mask$ have a binary representation where a certain bit is $1$, and the corresponding bit in the other element's binary representation is $0$. Such pairs of elements cannot satisfy the problem's requirements, so we need to move $j$ to the right until the bitwise AND result of $x$ and $mask$ is $0$.
73+
We use a variable $\textit{mask}$ to represent the bitwise OR result of the elements within the window. Next, we traverse each element of the array. For the current element $x$, if the bitwise AND result of $\textit{mask}$ and $x$ is not $0$, it means that the current element $x$ has overlapping binary bits with the elements in the window. At this point, we need to move the left pointer $l$ until the bitwise AND result of $\textit{mask}$ and $x$ is $0$. Then, we assign the bitwise OR result of $\textit{mask}$ and $x$ to $\textit{mask}$ and update the answer $\textit{ans} = \max(\textit{ans}, r - l + 1)$.
7474

75-
At this point, we have found a subarray that satisfies the problem's requirements. Its length is $i - j + 1$. We compare it with the length of the current longest elegant subarray. If it is longer than the current longest elegant subarray, we update the length of the longest elegant subarray.
75+
After the traversal, return the answer $\textit{ans}$.
7676

77-
Then we perform a bitwise OR operation between $mask$ and $x$, and continue to the next element.
78-
79-
Finally, the length of the longest elegant subarray we obtain is the answer.
80-
81-
The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the array $nums$.
77+
The time complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$. The space complexity is $O(1)$.
8278

8379
<!-- tabs:start -->
8480

@@ -87,13 +83,13 @@ The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is
8783
```python
8884
class Solution:
8985
def longestNiceSubarray(self, nums: List[int]) -> int:
90-
ans = j = mask = 0
91-
for i, x in enumerate(nums):
86+
ans = mask = l = 0
87+
for r, x in enumerate(nums):
9288
while mask & x:
93-
mask ^= nums[j]
94-
j += 1
95-
ans = max(ans, i - j + 1)
89+
mask ^= nums[l]
90+
l += 1
9691
mask |= x
92+
ans = max(ans, r - l + 1)
9793
return ans
9894
```
9995

@@ -103,12 +99,12 @@ class Solution:
10399
class Solution {
104100
public int longestNiceSubarray(int[] nums) {
105101
int ans = 0, mask = 0;
106-
for (int i = 0, j = 0; i < nums.length; ++i) {
107-
while ((mask & nums[i]) != 0) {
108-
mask ^= nums[j++];
102+
for (int l = 0, r = 0; r < nums.length; ++r) {
103+
while ((mask & nums[r]) != 0) {
104+
mask ^= nums[l++];
109105
}
110-
ans = Math.max(ans, i - j + 1);
111-
mask |= nums[i];
106+
mask |= nums[r];
107+
ans = Math.max(ans, r - l + 1);
112108
}
113109
return ans;
114110
}
@@ -122,12 +118,12 @@ class Solution {
122118
public:
123119
int longestNiceSubarray(vector<int>& nums) {
124120
int ans = 0, mask = 0;
125-
for (int i = 0, j = 0; i < nums.size(); ++i) {
126-
while (mask & nums[i]) {
127-
mask ^= nums[j++];
121+
for (int l = 0, r = 0; r < nums.size(); ++r) {
122+
while (mask & nums[r]) {
123+
mask ^= nums[l++];
128124
}
129-
ans = max(ans, i - j + 1);
130-
mask |= nums[i];
125+
mask |= nums[r];
126+
ans = max(ans, r - l + 1);
131127
}
132128
return ans;
133129
}
@@ -138,15 +134,14 @@ public:
138134
139135
```go
140136
func longestNiceSubarray(nums []int) (ans int) {
141-
mask, j := 0, 0
142-
for i, x := range nums {
143-
for ; mask&x != 0; j++ {
144-
mask ^= nums[j]
145-
}
146-
if k := i - j + 1; ans < k {
147-
ans = k
137+
mask, l := 0, 0
138+
for r, x := range nums {
139+
for mask&x != 0 {
140+
mask ^= nums[l]
141+
l++
148142
}
149143
mask |= x
144+
ans = max(ans, r-l+1)
150145
}
151146
return
152147
}
@@ -156,14 +151,13 @@ func longestNiceSubarray(nums []int) (ans int) {
156151

157152
```ts
158153
function longestNiceSubarray(nums: number[]): number {
159-
let mask = 0;
160-
let ans = 0;
161-
for (let i = 0, j = 0; i < nums.length; ++i) {
162-
while ((mask & nums[i]) !== 0) {
163-
mask ^= nums[j++];
154+
let [ans, mask] = [0, 0];
155+
for (let l = 0, r = 0; r < nums.length; ++r) {
156+
while (mask & nums[r]) {
157+
mask ^= nums[l++];
164158
}
165-
ans = Math.max(ans, i - j + 1);
166-
mask |= nums[i];
159+
mask |= nums[r];
160+
ans = Math.max(ans, r - l + 1);
167161
}
168162
return ans;
169163
}
@@ -176,19 +170,16 @@ impl Solution {
176170
pub fn longest_nice_subarray(nums: Vec<i32>) -> i32 {
177171
let mut ans = 0;
178172
let mut mask = 0;
179-
let mut j = 0;
180-
181-
for (i, &x) in nums.iter().enumerate() {
182-
let mut x = x;
183-
while (mask & x) != 0 {
184-
mask ^= nums[j];
185-
j += 1;
173+
let mut l = 0;
174+
for (r, &x) in nums.iter().enumerate() {
175+
while mask & x != 0 {
176+
mask ^= nums[l];
177+
l += 1;
186178
}
187-
ans = ans.max(i - j + 1);
188179
mask |= x;
180+
ans = ans.max((r - l + 1) as i32);
189181
}
190-
191-
ans as i32
182+
ans
192183
}
193184
}
194185
```
@@ -199,12 +190,12 @@ impl Solution {
199190
public class Solution {
200191
public int LongestNiceSubarray(int[] nums) {
201192
int ans = 0, mask = 0;
202-
for (int i = 0, j = 0; i < nums.Length; ++i) {
203-
while ((mask & nums[i]) != 0) {
204-
mask ^= nums[j++];
193+
for (int l = 0, r = 0; r < nums.Length; ++r) {
194+
while ((mask & nums[r]) != 0) {
195+
mask ^= nums[l++];
205196
}
206-
ans = Math.Max(ans, i - j + 1);
207-
mask |= nums[i];
197+
mask |= nums[r];
198+
ans = Math.Max(ans, r - l + 1);
208199
}
209200
return ans;
210201
}

solution/2400-2499/2401.Longest Nice Subarray/Solution.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ class Solution {
22
public:
33
int longestNiceSubarray(vector<int>& nums) {
44
int ans = 0, mask = 0;
5-
for (int i = 0, j = 0; i < nums.size(); ++i) {
6-
while (mask & nums[i]) {
7-
mask ^= nums[j++];
5+
for (int l = 0, r = 0; r < nums.size(); ++r) {
6+
while (mask & nums[r]) {
7+
mask ^= nums[l++];
88
}
9-
ans = max(ans, i - j + 1);
10-
mask |= nums[i];
9+
mask |= nums[r];
10+
ans = max(ans, r - l + 1);
1111
}
1212
return ans;
1313
}
14-
};
14+
};
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
public class Solution {
22
public int LongestNiceSubarray(int[] nums) {
33
int ans = 0, mask = 0;
4-
for (int i = 0, j = 0; i < nums.Length; ++i) {
5-
while ((mask & nums[i]) != 0) {
6-
mask ^= nums[j++];
4+
for (int l = 0, r = 0; r < nums.Length; ++r) {
5+
while ((mask & nums[r]) != 0) {
6+
mask ^= nums[l++];
77
}
8-
ans = Math.Max(ans, i - j + 1);
9-
mask |= nums[i];
8+
mask |= nums[r];
9+
ans = Math.Max(ans, r - l + 1);
1010
}
1111
return ans;
1212
}
13-
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
func longestNiceSubarray(nums []int) (ans int) {
2-
mask, j := 0, 0
3-
for i, x := range nums {
4-
for ; mask&x != 0; j++ {
5-
mask ^= nums[j]
6-
}
7-
if k := i - j + 1; ans < k {
8-
ans = k
2+
mask, l := 0, 0
3+
for r, x := range nums {
4+
for mask&x != 0 {
5+
mask ^= nums[l]
6+
l++
97
}
108
mask |= x
9+
ans = max(ans, r-l+1)
1110
}
1211
return
13-
}
12+
}

0 commit comments

Comments
 (0)