Skip to content

Commit f18b506

Browse files
authored
feat: add solutions to lc problems: No.3095~3097 (#2523)
* No.3095.Shortest Subarray With OR at Least K I * No.3096.Minimum Levels to Gain More Points * No.3097.Shortest Subarray With OR at Least K II
1 parent 487a57e commit f18b506

File tree

11 files changed

+284
-11
lines changed

11 files changed

+284
-11
lines changed

solution/3000-3099/3095.Shortest Subarray With OR at Least K I/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@
6666

6767
### 方法一:双指针 + 计数
6868

69+
我们可以发现,如果我们固定子数组的左端点,随着右端点向右移动,子数组的按位或值只会增大,不会减小。因此我们可以使用双指针的方法,维护一个满足条件的子数组。
70+
71+
具体地,我们使用两个指针 $i$ 和 $j$ 分别表示子数组的左右端点,初始时两个指针都位于数组的第一个元素。用一个变量 $s$ 表示子数组的按位或值,初始时 $s$ 的值为 $0$。我们还需要维护一个长度为 $32$ 的数组 $cnt$,表示子数组中每个元素的二进制表示中每一位的出现次数。
72+
73+
在每一步操作中,我们将 $j$ 向右移动一位,更新 $s$ 和 $cnt$。如果 $s$ 的值大于等于 $k$,我们不断更新子数组的最小长度,并将 $i$ 向右移动一位,直到 $s$ 的值小于 $k$。在这个过程中,我们也需要更新 $s$ 和 $cnt$。
74+
75+
最后,我们返回最小长度,如果不存在满足条件的子数组,则返回 $-1$。
76+
77+
时间复杂度 $O(n \times \log M)$,空间复杂度 $O(\log M)$,其中 $n$ 和 $M$ 分别是数组的长度和数组中元素的最大值。
78+
6979
<!-- tabs:start -->
7080

7181
```python

solution/3000-3099/3095.Shortest Subarray With OR at Least K I/README_EN.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,17 @@
6060

6161
## Solutions
6262

63-
### Solution 1
63+
### Solution 1: Two Pointers + Counting
64+
65+
We can observe that if we fix the left endpoint of the subarray, as the right endpoint moves to the right, the bitwise OR value of the subarray will only increase, not decrease. Therefore, we can use the double pointers method to maintain a subarray that meets the conditions.
66+
67+
Specifically, we use two pointers $i$ and $j$ to represent the left and right endpoints of the subarray, respectively. Initially, both pointers are at the first element of the array. We use a variable $s$ to represent the bitwise OR value of the subarray, and initially, the value of $s$ is $0$. We also need to maintain an array $cnt$ of length $32$, which represents the occurrence times of each bit in the binary representation of each element in the subarray.
68+
69+
In each step, we move $j$ to the right by one position, and update $s$ and $cnt$. If the value of $s$ is greater than or equal to $k$, we continuously update the minimum length of the subarray and move $i$ to the right by one position until the value of $s$ is less than $k$. In this process, we also need to update $s$ and $cnt$.
70+
71+
Finally, we return the minimum length. If there is no subarray that meets the conditions, we return $-1$.
72+
73+
The time complexity is $O(n \times \log M)$ and the space complexity is $O(\log M)$, where $n$ and $M$ are the length of the array and the maximum value of the elements in the array, respectively.
6474

6575
<!-- tabs:start -->
6676

solution/3000-3099/3096.Minimum Levels to Gain More Points/README.md

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,24 +86,104 @@
8686

8787
## 解法
8888

89-
### 方法一
89+
### 方法一:枚举
90+
91+
我们先计算得到两个玩家能得到的分数和,记为 $s$。
92+
93+
然后我们从小到大枚举玩家 $1$ 能完成的关卡数目 $i$,计算玩家 $1$ 得到的分数和 $t$,如果 $t > s - t$,那么玩家 $1$ 需要完成的关卡数目就是 $i$。
94+
95+
如果枚举完前 $n - 1$ 个关卡都没有找到满足条件的 $i$,那么就返回 $-1$。
96+
97+
时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$。
9098

9199
<!-- tabs:start -->
92100

93101
```python
94-
102+
class Solution:
103+
def minimumLevels(self, possible: List[int]) -> int:
104+
s = sum(-1 if x == 0 else 1 for x in possible)
105+
t = 0
106+
for i, x in enumerate(possible[:-1], 1):
107+
t += -1 if x == 0 else 1
108+
if t > s - t:
109+
return i
110+
return -1
95111
```
96112

97113
```java
98-
114+
class Solution {
115+
public int minimumLevels(int[] possible) {
116+
int s = 0;
117+
for (int x : possible) {
118+
s += x == 0 ? -1 : 1;
119+
}
120+
int t = 0;
121+
for (int i = 1; i < possible.length; ++i) {
122+
t += possible[i - 1] == 0 ? -1 : 1;
123+
if (t > s - t) {
124+
return i;
125+
}
126+
}
127+
return -1;
128+
}
129+
}
99130
```
100131

101132
```cpp
102-
133+
class Solution {
134+
public:
135+
int minimumLevels(vector<int>& possible) {
136+
int s = 0;
137+
for (int x : possible) {
138+
s += x == 0 ? -1 : 1;
139+
}
140+
int t = 0;
141+
for (int i = 1; i < possible.size(); ++i) {
142+
t += possible[i - 1] == 0 ? -1 : 1;
143+
if (t > s - t) {
144+
return i;
145+
}
146+
}
147+
return -1;
148+
}
149+
};
103150
```
104151
105152
```go
153+
func minimumLevels(possible []int) int {
154+
s := 0
155+
for _, x := range possible {
156+
if x == 0 {
157+
x = -1
158+
}
159+
s += x
160+
}
161+
t := 0
162+
for i, x := range possible[:len(possible)-1] {
163+
if x == 0 {
164+
x = -1
165+
}
166+
t += x
167+
if t > s-t {
168+
return i + 1
169+
}
170+
}
171+
return -1
172+
}
173+
```
106174

175+
```ts
176+
function minimumLevels(possible: number[]): number {
177+
const s = possible.reduce((acc, x) => acc + (x === 0 ? -1 : 1), 0);
178+
let t = 0;
179+
for (let i = 1; i < possible.length; ++i) {
180+
t += possible[i - 1] === 0 ? -1 : 1;
181+
if (t > s - t) {
182+
return i;
183+
}
184+
}
185+
return -1;
186+
}
107187
```
108188

109189
<!-- tabs:end -->

solution/3000-3099/3096.Minimum Levels to Gain More Points/README_EN.md

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,24 +82,104 @@
8282

8383
## Solutions
8484

85-
### Solution 1
85+
### Solution 1: Enumeration
86+
87+
First, we calculate the sum of the scores that both players can get, denoted as $s$.
88+
89+
Then, we enumerate the number of levels that player 1 can complete, denoted as $i$, in ascending order. We calculate the sum of the scores that player 1 gets, denoted as $t$. If $t > s - t$, then the number of levels that player 1 needs to complete is $i$.
90+
91+
If we have enumerated the first $n - 1$ levels and have not found a satisfying $i$, then we return $-1$.
92+
93+
The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$.
8694

8795
<!-- tabs:start -->
8896

8997
```python
90-
98+
class Solution:
99+
def minimumLevels(self, possible: List[int]) -> int:
100+
s = sum(-1 if x == 0 else 1 for x in possible)
101+
t = 0
102+
for i, x in enumerate(possible[:-1], 1):
103+
t += -1 if x == 0 else 1
104+
if t > s - t:
105+
return i
106+
return -1
91107
```
92108

93109
```java
94-
110+
class Solution {
111+
public int minimumLevels(int[] possible) {
112+
int s = 0;
113+
for (int x : possible) {
114+
s += x == 0 ? -1 : 1;
115+
}
116+
int t = 0;
117+
for (int i = 1; i < possible.length; ++i) {
118+
t += possible[i - 1] == 0 ? -1 : 1;
119+
if (t > s - t) {
120+
return i;
121+
}
122+
}
123+
return -1;
124+
}
125+
}
95126
```
96127

97128
```cpp
98-
129+
class Solution {
130+
public:
131+
int minimumLevels(vector<int>& possible) {
132+
int s = 0;
133+
for (int x : possible) {
134+
s += x == 0 ? -1 : 1;
135+
}
136+
int t = 0;
137+
for (int i = 1; i < possible.size(); ++i) {
138+
t += possible[i - 1] == 0 ? -1 : 1;
139+
if (t > s - t) {
140+
return i;
141+
}
142+
}
143+
return -1;
144+
}
145+
};
99146
```
100147
101148
```go
149+
func minimumLevels(possible []int) int {
150+
s := 0
151+
for _, x := range possible {
152+
if x == 0 {
153+
x = -1
154+
}
155+
s += x
156+
}
157+
t := 0
158+
for i, x := range possible[:len(possible)-1] {
159+
if x == 0 {
160+
x = -1
161+
}
162+
t += x
163+
if t > s-t {
164+
return i + 1
165+
}
166+
}
167+
return -1
168+
}
169+
```
102170

171+
```ts
172+
function minimumLevels(possible: number[]): number {
173+
const s = possible.reduce((acc, x) => acc + (x === 0 ? -1 : 1), 0);
174+
let t = 0;
175+
for (let i = 1; i < possible.length; ++i) {
176+
t += possible[i - 1] === 0 ? -1 : 1;
177+
if (t > s - t) {
178+
return i;
179+
}
180+
}
181+
return -1;
182+
}
103183
```
104184

105185
<!-- tabs:end -->
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution {
2+
public:
3+
int minimumLevels(vector<int>& possible) {
4+
int s = 0;
5+
for (int x : possible) {
6+
s += x == 0 ? -1 : 1;
7+
}
8+
int t = 0;
9+
for (int i = 1; i < possible.size(); ++i) {
10+
t += possible[i - 1] == 0 ? -1 : 1;
11+
if (t > s - t) {
12+
return i;
13+
}
14+
}
15+
return -1;
16+
}
17+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
func minimumLevels(possible []int) int {
2+
s := 0
3+
for _, x := range possible {
4+
if x == 0 {
5+
x = -1
6+
}
7+
s += x
8+
}
9+
t := 0
10+
for i, x := range possible[:len(possible)-1] {
11+
if x == 0 {
12+
x = -1
13+
}
14+
t += x
15+
if t > s-t {
16+
return i + 1
17+
}
18+
}
19+
return -1
20+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution {
2+
public int minimumLevels(int[] possible) {
3+
int s = 0;
4+
for (int x : possible) {
5+
s += x == 0 ? -1 : 1;
6+
}
7+
int t = 0;
8+
for (int i = 1; i < possible.length; ++i) {
9+
t += possible[i - 1] == 0 ? -1 : 1;
10+
if (t > s - t) {
11+
return i;
12+
}
13+
}
14+
return -1;
15+
}
16+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Solution:
2+
def minimumLevels(self, possible: List[int]) -> int:
3+
s = sum(-1 if x == 0 else 1 for x in possible)
4+
t = 0
5+
for i, x in enumerate(possible[:-1], 1):
6+
t += -1 if x == 0 else 1
7+
if t > s - t:
8+
return i
9+
return -1
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function minimumLevels(possible: number[]): number {
2+
const s = possible.reduce((acc, x) => acc + (x === 0 ? -1 : 1), 0);
3+
let t = 0;
4+
for (let i = 1; i < possible.length; ++i) {
5+
t += possible[i - 1] === 0 ? -1 : 1;
6+
if (t > s - t) {
7+
return i;
8+
}
9+
}
10+
return -1;
11+
}

solution/3000-3099/3097.Shortest Subarray With OR at Least K II/README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,17 @@
6464

6565
## 解法
6666

67-
### 方法一
67+
### 方法一:双指针 + 计数
68+
69+
我们可以发现,如果我们固定子数组的左端点,随着右端点向右移动,子数组的按位或值只会增大,不会减小。因此我们可以使用双指针的方法,维护一个满足条件的子数组。
70+
71+
具体地,我们使用两个指针 $i$ 和 $j$ 分别表示子数组的左右端点,初始时两个指针都位于数组的第一个元素。用一个变量 $s$ 表示子数组的按位或值,初始时 $s$ 的值为 $0$。我们还需要维护一个长度为 $32$ 的数组 $cnt$,表示子数组中每个元素的二进制表示中每一位的出现次数。
72+
73+
在每一步操作中,我们将 $j$ 向右移动一位,更新 $s$ 和 $cnt$。如果 $s$ 的值大于等于 $k$,我们不断更新子数组的最小长度,并将 $i$ 向右移动一位,直到 $s$ 的值小于 $k$。在这个过程中,我们也需要更新 $s$ 和 $cnt$。
74+
75+
最后,我们返回最小长度,如果不存在满足条件的子数组,则返回 $-1$。
76+
77+
时间复杂度 $O(n \times \log M)$,空间复杂度 $O(\log M)$,其中 $n$ 和 $M$ 分别是数组的长度和数组中元素的最大值。
6878

6979
<!-- tabs:start -->
7080

0 commit comments

Comments
 (0)