Skip to content

Commit 86a1bda

Browse files
authored
feat: add solutions to lc problems: No.2970~2973 (doocs#2160)
1 parent adfada1 commit 86a1bda

File tree

28 files changed

+1509
-23
lines changed

28 files changed

+1509
-23
lines changed

solution/2900-2999/2970.Count the Number of Incremovable Subarrays I/README.md

+135-3
Original file line numberDiff line numberDiff line change
@@ -56,34 +56,166 @@ nums 中只有这 7 个移除递增子数组。
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59+
**方法一:双指针**
60+
61+
根据题目描述,移除一个子数组后,剩余元素严格递增,那么存在以下几种情况:
62+
63+
1. 剩余元素仅包含数组 $nums$ 的前缀(可以为空);
64+
1. 剩余元素仅包含数组 $nums$ 的后缀;
65+
1. 剩余元素包含数组 $nums$ 的前缀和后缀。
66+
67+
其中第 $2$ 和第 $3$ 种情况可以合并为一种情况,即剩余元素包含数组 $nums$ 的后缀。即一共有以下两种情况:
68+
69+
1. 剩余元素仅包含数组 $nums$ 的前缀(可以为空);
70+
1. 剩余元素包含数组 $nums$ 的后缀。
71+
72+
我们先考虑第一种情况,即剩余元素仅包含数组 $nums$ 的前缀。我们可以用一个指针 $i$ 指向数组 $nums$ 的最长递增前缀的最后一个元素,即 $nums[0] \lt nums[1] \lt \cdots \lt nums[i]$,那么剩余元素的个数为 $n - i - 1$,其中 $n$ 为数组 $nums$ 的长度。因此,对于这种情况,要使得剩余元素严格递增,我们可以选择移除以下子数组:
73+
74+
1. $nums[i+1,...,n-1]$;
75+
1. $nums[i,...,n-1]$;
76+
1. $nums[i-1,...,n-1]$;
77+
1. $nums[i-2,...,n-1]$;
78+
1. $\cdots$;
79+
1. $nums[0,...,n-1]$。
80+
81+
这一共有 $i + 2$ 种情况,因此对于这种情况,移除递增子数组的数目为 $i + 2$。
82+
83+
再考虑第二种情况,即剩余元素包含数组 $nums$ 的后缀。我们可以用一个指针 $j$ 指向数组 $nums$ 的递增后缀的第一个元素,我们在 $[n - 1,...,1]$ 的范围内枚举 $j$ 作为递增后缀的第一个元素,每一次,我们需要移动指针 $i$ 使得 $nums[i] \lt nums[j]$,那么移除递增子数组的数组增加 $i + 2$。当 $nums[j - 1] \ge nums[j]$ 时,我们停止枚举,因为此时后缀不是严格递增。
84+
85+
时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。
86+
5987
<!-- tabs:start -->
6088

6189
### **Python3**
6290

6391
<!-- 这里可写当前语言的特殊实现逻辑 -->
6492

6593
```python
66-
94+
class Solution:
95+
def incremovableSubarrayCount(self, nums: List[int]) -> int:
96+
i, n = 0, len(nums)
97+
while i + 1 < n and nums[i] < nums[i + 1]:
98+
i += 1
99+
if i == n - 1:
100+
return n * (n + 1) // 2
101+
ans = i + 2
102+
j = n - 1
103+
while j:
104+
while i >= 0 and nums[i] >= nums[j]:
105+
i -= 1
106+
ans += i + 2
107+
if nums[j - 1] >= nums[j]:
108+
break
109+
j -= 1
110+
return ans
67111
```
68112

69113
### **Java**
70114

71115
<!-- 这里可写当前语言的特殊实现逻辑 -->
72116

73117
```java
74-
118+
class Solution {
119+
public int incremovableSubarrayCount(int[] nums) {
120+
int i = 0, n = nums.length;
121+
while (i + 1 < n && nums[i] < nums[i + 1]) {
122+
++i;
123+
}
124+
if (i == n - 1) {
125+
return n * (n + 1) / 2;
126+
}
127+
int ans = i + 2;
128+
for (int j = n - 1; j > 0; --j) {
129+
while (i >= 0 && nums[i] >= nums[j]) {
130+
--i;
131+
}
132+
ans += i + 2;
133+
if (nums[j - 1] >= nums[j]) {
134+
break;
135+
}
136+
}
137+
return ans;
138+
}
139+
}
75140
```
76141

77142
### **C++**
78143

79144
```cpp
80-
145+
class Solution {
146+
public:
147+
int incremovableSubarrayCount(vector<int>& nums) {
148+
int i = 0, n = nums.size();
149+
while (i + 1 < n && nums[i] < nums[i + 1]) {
150+
++i;
151+
}
152+
if (i == n - 1) {
153+
return n * (n + 1) / 2;
154+
}
155+
int ans = i + 2;
156+
for (int j = n - 1; j > 0; --j) {
157+
while (i >= 0 && nums[i] >= nums[j]) {
158+
--i;
159+
}
160+
ans += i + 2;
161+
if (nums[j - 1] >= nums[j]) {
162+
break;
163+
}
164+
}
165+
return ans;
166+
}
167+
};
81168
```
82169
83170
### **Go**
84171
85172
```go
173+
func incremovableSubarrayCount(nums []int) int {
174+
i, n := 0, len(nums)
175+
for i+1 < n && nums[i] < nums[i+1] {
176+
i++
177+
}
178+
if i == n-1 {
179+
return n * (n + 1) / 2
180+
}
181+
ans := i + 2
182+
for j := n - 1; j > 0; j-- {
183+
for i >= 0 && nums[i] >= nums[j] {
184+
i--
185+
}
186+
ans += i + 2
187+
if nums[j-1] >= nums[j] {
188+
break
189+
}
190+
}
191+
return ans
192+
}
193+
```
86194

195+
### **TypeScript**
196+
197+
```ts
198+
function incremovableSubarrayCount(nums: number[]): number {
199+
const n = nums.length;
200+
let i = 0;
201+
while (i + 1 < n && nums[i] < nums[i + 1]) {
202+
i++;
203+
}
204+
if (i === n - 1) {
205+
return (n * (n + 1)) / 2;
206+
}
207+
let ans = i + 2;
208+
for (let j = n - 1; j; --j) {
209+
while (i >= 0 && nums[i] >= nums[j]) {
210+
--i;
211+
}
212+
ans += i + 2;
213+
if (nums[j - 1] >= nums[j]) {
214+
break;
215+
}
216+
}
217+
return ans;
218+
}
87219
```
88220

89221
### **...**

solution/2900-2999/2970.Count the Number of Incremovable Subarrays I/README_EN.md

+135-3
Original file line numberDiff line numberDiff line change
@@ -50,30 +50,162 @@ It can be shown that there are only 7 incremovable subarrays in nums.
5050

5151
## Solutions
5252

53+
**Solution 1: Two Pointers**
54+
55+
According to the problem description, after removing a subarray, the remaining elements are strictly increasing. Therefore, there are several situations:
56+
57+
1. The remaining elements only include the prefix of the array $nums$ (which can be empty);
58+
2. The remaining elements only include the suffix of the array $nums$;
59+
3. The remaining elements include both the prefix and the suffix of the array $nums$.
60+
61+
The second and third situations can be combined into one, that is, the remaining elements include the suffix of the array $nums$. So there are two situations in total:
62+
63+
1. The remaining elements only include the prefix of the array $nums$ (which can be empty);
64+
2. The remaining elements include the suffix of the array $nums$.
65+
66+
First, consider the first situation, that is, the remaining elements only include the prefix of the array $nums$. We can use a pointer $i$ to point to the last element of the longest increasing prefix of the array $nums$, that is, $nums[0] \lt nums[1] \lt \cdots \lt nums[i]$, then the number of remaining elements is $n - i - 1$, where $n$ is the length of the array $nums$. Therefore, for this situation, to make the remaining elements strictly increasing, we can choose to remove the following subarrays:
67+
68+
1. $nums[i+1,...,n-1]$;
69+
2. $nums[i,...,n-1]$;
70+
3. $nums[i-1,...,n-1]$;
71+
4. $nums[i-2,...,n-1]$;
72+
5. $\cdots$;
73+
6. $nums[0,...,n-1]$.
74+
75+
There are $i + 2$ situations in total, so for this situation, the number of removed increasing subarrays is $i + 2$.
76+
77+
Next, consider the second situation, that is, the remaining elements include the suffix of the array $nums$. We can use a pointer $j$ to point to the first element of the increasing suffix of the array $nums$. We enumerate $j$ as the first element of the increasing suffix in the range $[n - 1,...,1]$. Each time, we need to move the pointer $i$ to make $nums[i] \lt nums[j]$, then the number of removed increasing subarrays increases by $i + 2$. When $nums[j - 1] \ge nums[j]$, we stop enumerating because the suffix is not strictly increasing at this time.
78+
79+
The time complexity is $O(n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$.
80+
5381
<!-- tabs:start -->
5482

5583
### **Python3**
5684

5785
```python
58-
86+
class Solution:
87+
def incremovableSubarrayCount(self, nums: List[int]) -> int:
88+
i, n = 0, len(nums)
89+
while i + 1 < n and nums[i] < nums[i + 1]:
90+
i += 1
91+
if i == n - 1:
92+
return n * (n + 1) // 2
93+
ans = i + 2
94+
j = n - 1
95+
while j:
96+
while i >= 0 and nums[i] >= nums[j]:
97+
i -= 1
98+
ans += i + 2
99+
if nums[j - 1] >= nums[j]:
100+
break
101+
j -= 1
102+
return ans
59103
```
60104

61105
### **Java**
62106

63107
```java
64-
108+
class Solution {
109+
public int incremovableSubarrayCount(int[] nums) {
110+
int i = 0, n = nums.length;
111+
while (i + 1 < n && nums[i] < nums[i + 1]) {
112+
++i;
113+
}
114+
if (i == n - 1) {
115+
return n * (n + 1) / 2;
116+
}
117+
int ans = i + 2;
118+
for (int j = n - 1; j > 0; --j) {
119+
while (i >= 0 && nums[i] >= nums[j]) {
120+
--i;
121+
}
122+
ans += i + 2;
123+
if (nums[j - 1] >= nums[j]) {
124+
break;
125+
}
126+
}
127+
return ans;
128+
}
129+
}
65130
```
66131

67132
### **C++**
68133

69134
```cpp
70-
135+
class Solution {
136+
public:
137+
int incremovableSubarrayCount(vector<int>& nums) {
138+
int i = 0, n = nums.size();
139+
while (i + 1 < n && nums[i] < nums[i + 1]) {
140+
++i;
141+
}
142+
if (i == n - 1) {
143+
return n * (n + 1) / 2;
144+
}
145+
int ans = i + 2;
146+
for (int j = n - 1; j > 0; --j) {
147+
while (i >= 0 && nums[i] >= nums[j]) {
148+
--i;
149+
}
150+
ans += i + 2;
151+
if (nums[j - 1] >= nums[j]) {
152+
break;
153+
}
154+
}
155+
return ans;
156+
}
157+
};
71158
```
72159
73160
### **Go**
74161
75162
```go
163+
func incremovableSubarrayCount(nums []int) int {
164+
i, n := 0, len(nums)
165+
for i+1 < n && nums[i] < nums[i+1] {
166+
i++
167+
}
168+
if i == n-1 {
169+
return n * (n + 1) / 2
170+
}
171+
ans := i + 2
172+
for j := n - 1; j > 0; j-- {
173+
for i >= 0 && nums[i] >= nums[j] {
174+
i--
175+
}
176+
ans += i + 2
177+
if nums[j-1] >= nums[j] {
178+
break
179+
}
180+
}
181+
return ans
182+
}
183+
```
76184

185+
### **TypeScript**
186+
187+
```ts
188+
function incremovableSubarrayCount(nums: number[]): number {
189+
const n = nums.length;
190+
let i = 0;
191+
while (i + 1 < n && nums[i] < nums[i + 1]) {
192+
i++;
193+
}
194+
if (i === n - 1) {
195+
return (n * (n + 1)) / 2;
196+
}
197+
let ans = i + 2;
198+
for (let j = n - 1; j; --j) {
199+
while (i >= 0 && nums[i] >= nums[j]) {
200+
--i;
201+
}
202+
ans += i + 2;
203+
if (nums[j - 1] >= nums[j]) {
204+
break;
205+
}
206+
}
207+
return ans;
208+
}
77209
```
78210

79211
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution {
2+
public:
3+
int incremovableSubarrayCount(vector<int>& nums) {
4+
int i = 0, n = nums.size();
5+
while (i + 1 < n && nums[i] < nums[i + 1]) {
6+
++i;
7+
}
8+
if (i == n - 1) {
9+
return n * (n + 1) / 2;
10+
}
11+
int ans = i + 2;
12+
for (int j = n - 1; j > 0; --j) {
13+
while (i >= 0 && nums[i] >= nums[j]) {
14+
--i;
15+
}
16+
ans += i + 2;
17+
if (nums[j - 1] >= nums[j]) {
18+
break;
19+
}
20+
}
21+
return ans;
22+
}
23+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
func incremovableSubarrayCount(nums []int) int {
2+
i, n := 0, len(nums)
3+
for i+1 < n && nums[i] < nums[i+1] {
4+
i++
5+
}
6+
if i == n-1 {
7+
return n * (n + 1) / 2
8+
}
9+
ans := i + 2
10+
for j := n - 1; j > 0; j-- {
11+
for i >= 0 && nums[i] >= nums[j] {
12+
i--
13+
}
14+
ans += i + 2
15+
if nums[j-1] >= nums[j] {
16+
break
17+
}
18+
}
19+
return ans
20+
}

0 commit comments

Comments
 (0)