Skip to content

Commit 023ed13

Browse files
authored
feat: add solutions for lc No.3891 (#5137)
1 parent a9beba0 commit 023ed13

7 files changed

Lines changed: 421 additions & 8 deletions

File tree

solution/3800-3899/3891.Minimum Increase to Maximize Special Indices/README.md

Lines changed: 147 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,32 +96,175 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3891.Mi
9696

9797
<!-- solution:start -->
9898

99-
### 方法一
99+
### 方法一:记忆化搜索
100+
101+
我们注意到,如果数组长度为奇数,那么将所有奇数下标的元素增加到比相邻元素都大 1 就可以得到最大数量的特殊下标;如果数组长度为偶数,那么将下标范围为 $[1, n - 2]$ 中的下标,跳过其中一个,剩余的元素,按隔一个元素选择一个的方式增加到比相邻元素都大 1 就可以得到最大数量的特殊下标。
102+
103+
因此,我们设计一个函数 $\text{dfs}(i, j)$,表示从下标 $i$ 开始,跳过 $j$ 个元素,得到的最大数量的特殊下标所需的最少操作数。对于每个下标 $i$,我们可以选择将其增加到比相邻元素都大 1,或者跳过它。我们使用记忆化搜索来避免重复计算。
104+
105+
函数 $\text{dfs}(i, j)$ 的实现如下:
106+
107+
- 如果 $i \geq n - 1$,返回 0。
108+
- 计算将 $nums[i]$ 增加到比相邻元素都大 1 所需的操作数,记为 $cost$。
109+
- 计算选择将 $nums[i]$ 增加到比相邻元素都大 1 的总操作数 $cost + \text{dfs}(i + 2, j)$。
110+
- 如果 $j > 0$,计算选择跳过 $nums[i]$ 的总操作数 $\text{dfs}(i + 1, 0)$,并更新 $ans$ 为两者的较小值。
111+
112+
最后,返回 $\mathrm{dfs}(1, (n \bmod 2) \oplus 1)$ 即可。
113+
114+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。
100115

101116
<!-- tabs:start -->
102117

103118
#### Python3
104119

105120
```python
106-
121+
class Solution:
122+
def minIncrease(self, nums: List[int]) -> int:
123+
@cache
124+
def dfs(i: int, j: int) -> int:
125+
if i >= len(nums) - 1:
126+
return 0
127+
cost = max(0, max(nums[i - 1], nums[i + 1]) + 1 - nums[i])
128+
ans = cost + dfs(i + 2, j)
129+
if j:
130+
ans = min(ans, dfs(i + 1, 0))
131+
return ans
132+
133+
return dfs(1, len(nums) & 1 ^ 1)
107134
```
108135

109136
#### Java
110137

111138
```java
112-
139+
class Solution {
140+
private Long[][] f;
141+
private int[] nums;
142+
private int n;
143+
144+
public long minIncrease(int[] nums) {
145+
n = nums.length;
146+
this.nums = nums;
147+
f = new Long[n][2];
148+
return dfs(1, n & 1 ^ 1);
149+
}
150+
151+
private long dfs(int i, int j) {
152+
if (i >= n - 1) {
153+
return 0;
154+
}
155+
if (f[i][j] != null) {
156+
return f[i][j];
157+
}
158+
int cost = Math.max(0, Math.max(nums[i - 1], nums[i + 1]) + 1 - nums[i]);
159+
long ans = cost + dfs(i + 2, j);
160+
if (j > 0) {
161+
ans = Math.min(ans, dfs(i + 1, 0));
162+
}
163+
return f[i][j] = ans;
164+
}
165+
}
113166
```
114167

115168
#### C++
116169

117170
```cpp
118-
171+
class Solution {
172+
private:
173+
vector<vector<long long>> f;
174+
vector<int> nums;
175+
int n;
176+
177+
public:
178+
long long minIncrease(vector<int>& nums) {
179+
this->nums = nums;
180+
n = nums.size();
181+
f.assign(n, vector<long long>(2, -1));
182+
return dfs(1, (n & 1) ^ 1);
183+
}
184+
185+
long long dfs(int i, int j) {
186+
if (i >= n - 1) {
187+
return 0;
188+
}
189+
if (f[i][j] != -1) {
190+
return f[i][j];
191+
}
192+
int cost = max(0, max(nums[i - 1], nums[i + 1]) + 1 - nums[i]);
193+
long long ans = cost + dfs(i + 2, j);
194+
if (j > 0) {
195+
ans = min(ans, dfs(i + 1, 0));
196+
}
197+
return f[i][j] = ans;
198+
}
199+
};
119200
```
120201

121202
#### Go
122203

123204
```go
205+
func minIncrease(nums []int) int64 {
206+
n := len(nums)
207+
208+
f := make([][]int64, n)
209+
for i := range f {
210+
f[i] = []int64{-1, -1}
211+
}
212+
213+
var dfs func(i, j int) int64
214+
dfs = func(i, j int) int64 {
215+
if i >= n-1 {
216+
return 0
217+
}
218+
if f[i][j] != -1 {
219+
return f[i][j]
220+
}
221+
222+
cost := max(0, max(nums[i-1], nums[i+1])+1-nums[i])
223+
ans := int64(cost) + dfs(i+2, j)
224+
225+
if j > 0 {
226+
if t := dfs(i+1, 0); t < ans {
227+
ans = t
228+
}
229+
}
230+
231+
f[i][j] = ans
232+
return ans
233+
}
234+
235+
return dfs(1, (n&1)^1)
236+
}
237+
```
238+
239+
#### TypeScript
240+
241+
```ts
242+
function minIncrease(nums: number[]): number {
243+
const n = nums.length;
244+
245+
const f: number[][] = Array.from({ length: n }, () => Array(2).fill(-1));
246+
247+
const dfs = (i: number, j: number): number => {
248+
if (i >= n - 1) {
249+
return 0;
250+
}
251+
if (f[i][j] !== -1) {
252+
return f[i][j];
253+
}
254+
255+
const cost = Math.max(0, Math.max(nums[i - 1], nums[i + 1]) + 1 - nums[i]);
256+
let ans = cost + dfs(i + 2, j);
257+
258+
if (j > 0) {
259+
ans = Math.min(ans, dfs(i + 1, 0));
260+
}
261+
262+
f[i][j] = ans;
263+
return ans;
264+
};
124265

266+
return dfs(1, (n & 1) ^ 1);
267+
}
125268
```
126269

127270
<!-- tabs:end -->

solution/3800-3899/3891.Minimum Increase to Maximize Special Indices/README_EN.md

Lines changed: 147 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,32 +94,175 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3891.Mi
9494

9595
<!-- solution:start -->
9696

97-
### Solution 1
97+
### Solution 1: Memoized Search
98+
99+
We observe that if the array length is odd, then increasing all elements at odd indices so that each is $1$ greater than both adjacent elements yields the maximum possible number of special indices. If the array length is even, then among indices in the range $[1, n - 2]$, we skip exactly one index, and for the remaining indices, increase every other element so that each is $1$ greater than both adjacent elements; this also yields the maximum possible number of special indices.
100+
101+
Therefore, we design a function $\text{dfs}(i, j)$, which represents the minimum number of operations needed to obtain the maximum number of special indices starting from index $i$, with $j$ remaining skips. For each index $i$, we can either increase it so that it is $1$ greater than both neighbors, or skip it. We use memoized search to avoid repeated computation.
102+
103+
The implementation of $\text{dfs}(i, j)$ is as follows:
104+
105+
- If $i \geq n - 1$, return $0$.
106+
- Compute the number of operations required to increase $nums[i]$ so that it is $1$ greater than both adjacent elements, denoted as $cost$.
107+
- Compute the total cost for choosing to increase $nums[i]$: $cost + \text{dfs}(i + 2, j)$.
108+
- If $j > 0$, compute the total cost for choosing to skip $nums[i]$: $\text{dfs}(i + 1, 0)$, and update $ans$ to the smaller of the two.
109+
110+
Finally, return $\text{dfs}(1, (n \bmod 2) \oplus 1)$.
111+
112+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array.
98113

99114
<!-- tabs:start -->
100115

101116
#### Python3
102117

103118
```python
104-
119+
class Solution:
120+
def minIncrease(self, nums: List[int]) -> int:
121+
@cache
122+
def dfs(i: int, j: int) -> int:
123+
if i >= len(nums) - 1:
124+
return 0
125+
cost = max(0, max(nums[i - 1], nums[i + 1]) + 1 - nums[i])
126+
ans = cost + dfs(i + 2, j)
127+
if j:
128+
ans = min(ans, dfs(i + 1, 0))
129+
return ans
130+
131+
return dfs(1, len(nums) & 1 ^ 1)
105132
```
106133

107134
#### Java
108135

109136
```java
110-
137+
class Solution {
138+
private Long[][] f;
139+
private int[] nums;
140+
private int n;
141+
142+
public long minIncrease(int[] nums) {
143+
n = nums.length;
144+
this.nums = nums;
145+
f = new Long[n][2];
146+
return dfs(1, n & 1 ^ 1);
147+
}
148+
149+
private long dfs(int i, int j) {
150+
if (i >= n - 1) {
151+
return 0;
152+
}
153+
if (f[i][j] != null) {
154+
return f[i][j];
155+
}
156+
int cost = Math.max(0, Math.max(nums[i - 1], nums[i + 1]) + 1 - nums[i]);
157+
long ans = cost + dfs(i + 2, j);
158+
if (j > 0) {
159+
ans = Math.min(ans, dfs(i + 1, 0));
160+
}
161+
return f[i][j] = ans;
162+
}
163+
}
111164
```
112165

113166
#### C++
114167

115168
```cpp
116-
169+
class Solution {
170+
private:
171+
vector<vector<long long>> f;
172+
vector<int> nums;
173+
int n;
174+
175+
public:
176+
long long minIncrease(vector<int>& nums) {
177+
this->nums = nums;
178+
n = nums.size();
179+
f.assign(n, vector<long long>(2, -1));
180+
return dfs(1, (n & 1) ^ 1);
181+
}
182+
183+
long long dfs(int i, int j) {
184+
if (i >= n - 1) {
185+
return 0;
186+
}
187+
if (f[i][j] != -1) {
188+
return f[i][j];
189+
}
190+
int cost = max(0, max(nums[i - 1], nums[i + 1]) + 1 - nums[i]);
191+
long long ans = cost + dfs(i + 2, j);
192+
if (j > 0) {
193+
ans = min(ans, dfs(i + 1, 0));
194+
}
195+
return f[i][j] = ans;
196+
}
197+
};
117198
```
118199

119200
#### Go
120201

121202
```go
203+
func minIncrease(nums []int) int64 {
204+
n := len(nums)
205+
206+
f := make([][]int64, n)
207+
for i := range f {
208+
f[i] = []int64{-1, -1}
209+
}
210+
211+
var dfs func(i, j int) int64
212+
dfs = func(i, j int) int64 {
213+
if i >= n-1 {
214+
return 0
215+
}
216+
if f[i][j] != -1 {
217+
return f[i][j]
218+
}
219+
220+
cost := max(0, max(nums[i-1], nums[i+1])+1-nums[i])
221+
ans := int64(cost) + dfs(i+2, j)
222+
223+
if j > 0 {
224+
if t := dfs(i+1, 0); t < ans {
225+
ans = t
226+
}
227+
}
228+
229+
f[i][j] = ans
230+
return ans
231+
}
232+
233+
return dfs(1, (n&1)^1)
234+
}
235+
```
236+
237+
#### TypeScript
238+
239+
```ts
240+
function minIncrease(nums: number[]): number {
241+
const n = nums.length;
242+
243+
const f: number[][] = Array.from({ length: n }, () => Array(2).fill(-1));
244+
245+
const dfs = (i: number, j: number): number => {
246+
if (i >= n - 1) {
247+
return 0;
248+
}
249+
if (f[i][j] !== -1) {
250+
return f[i][j];
251+
}
252+
253+
const cost = Math.max(0, Math.max(nums[i - 1], nums[i + 1]) + 1 - nums[i]);
254+
let ans = cost + dfs(i + 2, j);
255+
256+
if (j > 0) {
257+
ans = Math.min(ans, dfs(i + 1, 0));
258+
}
259+
260+
f[i][j] = ans;
261+
return ans;
262+
};
122263

264+
return dfs(1, (n & 1) ^ 1);
265+
}
123266
```
124267

125268
<!-- tabs:end -->
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution {
2+
private:
3+
vector<vector<long long>> f;
4+
vector<int> nums;
5+
int n;
6+
7+
public:
8+
long long minIncrease(vector<int>& nums) {
9+
this->nums = nums;
10+
n = nums.size();
11+
f.assign(n, vector<long long>(2, -1));
12+
return dfs(1, (n & 1) ^ 1);
13+
}
14+
15+
long long dfs(int i, int j) {
16+
if (i >= n - 1) {
17+
return 0;
18+
}
19+
if (f[i][j] != -1) {
20+
return f[i][j];
21+
}
22+
int cost = max(0, max(nums[i - 1], nums[i + 1]) + 1 - nums[i]);
23+
long long ans = cost + dfs(i + 2, j);
24+
if (j > 0) {
25+
ans = min(ans, dfs(i + 1, 0));
26+
}
27+
return f[i][j] = ans;
28+
}
29+
};

0 commit comments

Comments
 (0)