Skip to content

Commit d1b2fdb

Browse files
authored
feat: update solutions to lc problems: No.375,276 (doocs#3013)
1 parent 90788e4 commit d1b2fdb

File tree

20 files changed

+394
-256
lines changed

20 files changed

+394
-256
lines changed

solution/0300-0399/0375.Guess Number Higher or Lower II/README.md

+55-39
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,13 @@ tags:
9090

9191
<!-- solution:start -->
9292

93-
### 方法一
93+
### 方法一:动态规划
94+
95+
我们定义 $f[i][j]$ 表示在区间 $[i, j]$ 中猜中任意一个数最少需要花费的钱数。初始时 $f[i][i] = 0$,因为猜中了唯一的数不需要花费,对于 $i \gt j$ 的情况,也有 $f[i][j] = 0$。答案即为 $f[1][n]$。
96+
97+
对于 $f[i][j]$,我们可以枚举 $[i, j]$ 中的任意一个数 $k$,将区间 $[i, j]$ 分为 $[i, k - 1]$ 和 $[k + 1, j]$ 两部分,选择其中的较大值加上 $k$ 的花费,即 $\max(f[i][k - 1], f[k + 1][j]) + k$ 的最小值。
98+
99+
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为猜测的数字范围。
94100

95101
<!-- tabs:start -->
96102

@@ -99,34 +105,30 @@ tags:
99105
```python
100106
class Solution:
101107
def getMoneyAmount(self, n: int) -> int:
102-
dp = [[0] * (n + 10) for _ in range(n + 10)]
103-
for l in range(2, n + 1):
104-
for i in range(1, n - l + 2):
105-
j = i + l - 1
106-
dp[i][j] = inf
107-
for k in range(i, j + 1):
108-
t = max(dp[i][k - 1], dp[k + 1][j]) + k
109-
dp[i][j] = min(dp[i][j], t)
110-
return dp[1][n]
108+
f = [[0] * (n + 1) for _ in range(n + 1)]
109+
for i in range(n - 1, 0, -1):
110+
for j in range(i + 1, n + 1):
111+
f[i][j] = j + f[i][j - 1]
112+
for k in range(i, j):
113+
f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k)
114+
return f[1][n]
111115
```
112116

113117
#### Java
114118

115119
```java
116120
class Solution {
117121
public int getMoneyAmount(int n) {
118-
int[][] dp = new int[n + 10][n + 10];
119-
for (int l = 2; l <= n; ++l) {
120-
for (int i = 1; i + l - 1 <= n; ++i) {
121-
int j = i + l - 1;
122-
dp[i][j] = Integer.MAX_VALUE;
123-
for (int k = i; k <= j; ++k) {
124-
int t = Math.max(dp[i][k - 1], dp[k + 1][j]) + k;
125-
dp[i][j] = Math.min(dp[i][j], t);
122+
int[][] f = new int[n + 1][n + 1];
123+
for (int i = n - 1; i > 0; --i) {
124+
for (int j = i + 1; j <= n; ++j) {
125+
f[i][j] = j + f[i][j - 1];
126+
for (int k = i; k < j; ++k) {
127+
f[i][j] = Math.min(f[i][j], Math.max(f[i][k - 1], f[k + 1][j]) + k);
126128
}
127129
}
128130
}
129-
return dp[1][n];
131+
return f[1][n];
130132
}
131133
}
132134
```
@@ -137,18 +139,17 @@ class Solution {
137139
class Solution {
138140
public:
139141
int getMoneyAmount(int n) {
140-
vector<vector<int>> dp(n + 10, vector<int>(n + 10));
141-
for (int l = 2; l <= n; ++l) {
142-
for (int i = 1; i + l - 1 <= n; ++i) {
143-
int j = i + l - 1;
144-
dp[i][j] = INT_MAX;
145-
for (int k = i; k <= j; ++k) {
146-
int t = max(dp[i][k - 1], dp[k + 1][j]) + k;
147-
dp[i][j] = min(dp[i][j], t);
142+
int f[n + 1][n + 1];
143+
memset(f, 0, sizeof(f));
144+
for (int i = n - 1; i; --i) {
145+
for (int j = i + 1; j <= n; ++j) {
146+
f[i][j] = j + f[i][j - 1];
147+
for (int k = i; k < j; ++k) {
148+
f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k);
148149
}
149150
}
150151
}
151-
return dp[1][n];
152+
return f[1][n];
152153
}
153154
};
154155
```
@@ -157,21 +158,36 @@ public:
157158
158159
```go
159160
func getMoneyAmount(n int) int {
160-
dp := make([][]int, n+10)
161-
for i := 0; i < len(dp); i++ {
162-
dp[i] = make([]int, n+10)
161+
f := make([][]int, n+1)
162+
for i := range f {
163+
f[i] = make([]int, n+1)
163164
}
164-
for l := 2; l <= n; l++ {
165-
for i := 1; i+l-1 <= n; i++ {
166-
j := i + l - 1
167-
dp[i][j] = math.MaxInt32
168-
for k := i; k <= j; k++ {
169-
t := max(dp[i][k-1], dp[k+1][j]) + k
170-
dp[i][j] = min(dp[i][j], t)
165+
for i := n - 1; i > 0; i-- {
166+
for j := i + 1; j <= n; j++ {
167+
f[i][j] = j + f[i][j-1]
168+
for k := i; k < j; k++ {
169+
f[i][j] = min(f[i][j], k+max(f[i][k-1], f[k+1][j]))
171170
}
172171
}
173172
}
174-
return dp[1][n]
173+
return f[1][n]
174+
}
175+
```
176+
177+
#### TypeScript
178+
179+
```ts
180+
function getMoneyAmount(n: number): number {
181+
const f: number[][] = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
182+
for (let i = n - 1; i; --i) {
183+
for (let j = i + 1; j <= n; ++j) {
184+
f[i][j] = j + f[i][j - 1];
185+
for (let k = i; k < j; ++k) {
186+
f[i][j] = Math.min(f[i][j], k + Math.max(f[i][k - 1], f[k + 1][j]));
187+
}
188+
}
189+
}
190+
return f[1][n];
175191
}
176192
```
177193

solution/0300-0399/0375.Guess Number Higher or Lower II/README_EN.md

+53-39
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,11 @@ The worst case is that you pay $1.
8888

8989
<!-- solution:start -->
9090

91-
### Solution 1
91+
### Solution 1: Dynamic Programming
92+
93+
We define $f[i][j]$ as the minimum cost required to guess any number in the interval $[i, j]$. Initially, $f[i][i] = 0$ because there is no cost to guess the only number, and for $i > j$, we also have $f[i][j] = 0$. The answer is $f[1][n]$.
94+
95+
For $f[i][j]$, we can enumerate any number $k$ in $[i, j]$, divide the interval $[i, j]$ into two parts, $[i, k - 1]$ and $[k + 1, j]$, choose the larger value of the two parts plus the cost of $k$,
9296

9397
<!-- tabs:start -->
9498

@@ -97,34 +101,30 @@ The worst case is that you pay $1.
97101
```python
98102
class Solution:
99103
def getMoneyAmount(self, n: int) -> int:
100-
dp = [[0] * (n + 10) for _ in range(n + 10)]
101-
for l in range(2, n + 1):
102-
for i in range(1, n - l + 2):
103-
j = i + l - 1
104-
dp[i][j] = inf
105-
for k in range(i, j + 1):
106-
t = max(dp[i][k - 1], dp[k + 1][j]) + k
107-
dp[i][j] = min(dp[i][j], t)
108-
return dp[1][n]
104+
f = [[0] * (n + 1) for _ in range(n + 1)]
105+
for i in range(n - 1, 0, -1):
106+
for j in range(i + 1, n + 1):
107+
f[i][j] = j + f[i][j - 1]
108+
for k in range(i, j):
109+
f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k)
110+
return f[1][n]
109111
```
110112

111113
#### Java
112114

113115
```java
114116
class Solution {
115117
public int getMoneyAmount(int n) {
116-
int[][] dp = new int[n + 10][n + 10];
117-
for (int l = 2; l <= n; ++l) {
118-
for (int i = 1; i + l - 1 <= n; ++i) {
119-
int j = i + l - 1;
120-
dp[i][j] = Integer.MAX_VALUE;
121-
for (int k = i; k <= j; ++k) {
122-
int t = Math.max(dp[i][k - 1], dp[k + 1][j]) + k;
123-
dp[i][j] = Math.min(dp[i][j], t);
118+
int[][] f = new int[n + 1][n + 1];
119+
for (int i = n - 1; i > 0; --i) {
120+
for (int j = i + 1; j <= n; ++j) {
121+
f[i][j] = j + f[i][j - 1];
122+
for (int k = i; k < j; ++k) {
123+
f[i][j] = Math.min(f[i][j], Math.max(f[i][k - 1], f[k + 1][j]) + k);
124124
}
125125
}
126126
}
127-
return dp[1][n];
127+
return f[1][n];
128128
}
129129
}
130130
```
@@ -135,18 +135,17 @@ class Solution {
135135
class Solution {
136136
public:
137137
int getMoneyAmount(int n) {
138-
vector<vector<int>> dp(n + 10, vector<int>(n + 10));
139-
for (int l = 2; l <= n; ++l) {
140-
for (int i = 1; i + l - 1 <= n; ++i) {
141-
int j = i + l - 1;
142-
dp[i][j] = INT_MAX;
143-
for (int k = i; k <= j; ++k) {
144-
int t = max(dp[i][k - 1], dp[k + 1][j]) + k;
145-
dp[i][j] = min(dp[i][j], t);
138+
int f[n + 1][n + 1];
139+
memset(f, 0, sizeof(f));
140+
for (int i = n - 1; i; --i) {
141+
for (int j = i + 1; j <= n; ++j) {
142+
f[i][j] = j + f[i][j - 1];
143+
for (int k = i; k < j; ++k) {
144+
f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k);
146145
}
147146
}
148147
}
149-
return dp[1][n];
148+
return f[1][n];
150149
}
151150
};
152151
```
@@ -155,21 +154,36 @@ public:
155154
156155
```go
157156
func getMoneyAmount(n int) int {
158-
dp := make([][]int, n+10)
159-
for i := 0; i < len(dp); i++ {
160-
dp[i] = make([]int, n+10)
157+
f := make([][]int, n+1)
158+
for i := range f {
159+
f[i] = make([]int, n+1)
161160
}
162-
for l := 2; l <= n; l++ {
163-
for i := 1; i+l-1 <= n; i++ {
164-
j := i + l - 1
165-
dp[i][j] = math.MaxInt32
166-
for k := i; k <= j; k++ {
167-
t := max(dp[i][k-1], dp[k+1][j]) + k
168-
dp[i][j] = min(dp[i][j], t)
161+
for i := n - 1; i > 0; i-- {
162+
for j := i + 1; j <= n; j++ {
163+
f[i][j] = j + f[i][j-1]
164+
for k := i; k < j; k++ {
165+
f[i][j] = min(f[i][j], k+max(f[i][k-1], f[k+1][j]))
169166
}
170167
}
171168
}
172-
return dp[1][n]
169+
return f[1][n]
170+
}
171+
```
172+
173+
#### TypeScript
174+
175+
```ts
176+
function getMoneyAmount(n: number): number {
177+
const f: number[][] = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
178+
for (let i = n - 1; i; --i) {
179+
for (let j = i + 1; j <= n; ++j) {
180+
f[i][j] = j + f[i][j - 1];
181+
for (let k = i; k < j; ++k) {
182+
f[i][j] = Math.min(f[i][j], k + Math.max(f[i][k - 1], f[k + 1][j]));
183+
}
184+
}
185+
}
186+
return f[1][n];
173187
}
174188
```
175189

Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
class Solution {
22
public:
33
int getMoneyAmount(int n) {
4-
vector<vector<int>> dp(n + 10, vector<int>(n + 10));
5-
for (int l = 2; l <= n; ++l) {
6-
for (int i = 1; i + l - 1 <= n; ++i) {
7-
int j = i + l - 1;
8-
dp[i][j] = INT_MAX;
9-
for (int k = i; k <= j; ++k) {
10-
int t = max(dp[i][k - 1], dp[k + 1][j]) + k;
11-
dp[i][j] = min(dp[i][j], t);
4+
int f[n + 1][n + 1];
5+
memset(f, 0, sizeof(f));
6+
for (int i = n - 1; i; --i) {
7+
for (int j = i + 1; j <= n; ++j) {
8+
f[i][j] = j + f[i][j - 1];
9+
for (int k = i; k < j; ++k) {
10+
f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k);
1211
}
1312
}
1413
}
15-
return dp[1][n];
14+
return f[1][n];
1615
}
1716
};
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
func getMoneyAmount(n int) int {
2-
dp := make([][]int, n+10)
3-
for i := 0; i < len(dp); i++ {
4-
dp[i] = make([]int, n+10)
2+
f := make([][]int, n+1)
3+
for i := range f {
4+
f[i] = make([]int, n+1)
55
}
6-
for l := 2; l <= n; l++ {
7-
for i := 1; i+l-1 <= n; i++ {
8-
j := i + l - 1
9-
dp[i][j] = math.MaxInt32
10-
for k := i; k <= j; k++ {
11-
t := max(dp[i][k-1], dp[k+1][j]) + k
12-
dp[i][j] = min(dp[i][j], t)
6+
for i := n - 1; i > 0; i-- {
7+
for j := i + 1; j <= n; j++ {
8+
f[i][j] = j + f[i][j-1]
9+
for k := i; k < j; k++ {
10+
f[i][j] = min(f[i][j], k+max(f[i][k-1], f[k+1][j]))
1311
}
1412
}
1513
}
16-
return dp[1][n]
14+
return f[1][n]
1715
}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
class Solution {
22
public int getMoneyAmount(int n) {
3-
int[][] dp = new int[n + 10][n + 10];
4-
for (int l = 2; l <= n; ++l) {
5-
for (int i = 1; i + l - 1 <= n; ++i) {
6-
int j = i + l - 1;
7-
dp[i][j] = Integer.MAX_VALUE;
8-
for (int k = i; k <= j; ++k) {
9-
int t = Math.max(dp[i][k - 1], dp[k + 1][j]) + k;
10-
dp[i][j] = Math.min(dp[i][j], t);
3+
int[][] f = new int[n + 1][n + 1];
4+
for (int i = n - 1; i > 0; --i) {
5+
for (int j = i + 1; j <= n; ++j) {
6+
f[i][j] = j + f[i][j - 1];
7+
for (int k = i; k < j; ++k) {
8+
f[i][j] = Math.min(f[i][j], Math.max(f[i][k - 1], f[k + 1][j]) + k);
119
}
1210
}
1311
}
14-
return dp[1][n];
12+
return f[1][n];
1513
}
1614
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
class Solution:
22
def getMoneyAmount(self, n: int) -> int:
3-
dp = [[0] * (n + 10) for _ in range(n + 10)]
4-
for l in range(2, n + 1):
5-
for i in range(1, n - l + 2):
6-
j = i + l - 1
7-
dp[i][j] = inf
8-
for k in range(i, j + 1):
9-
t = max(dp[i][k - 1], dp[k + 1][j]) + k
10-
dp[i][j] = min(dp[i][j], t)
11-
return dp[1][n]
3+
f = [[0] * (n + 1) for _ in range(n + 1)]
4+
for i in range(n - 1, 0, -1):
5+
for j in range(i + 1, n + 1):
6+
f[i][j] = j + f[i][j - 1]
7+
for k in range(i, j):
8+
f[i][j] = min(f[i][j], max(f[i][k - 1], f[k + 1][j]) + k)
9+
return f[1][n]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function getMoneyAmount(n: number): number {
2+
const f: number[][] = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
3+
for (let i = n - 1; i; --i) {
4+
for (let j = i + 1; j <= n; ++j) {
5+
f[i][j] = j + f[i][j - 1];
6+
for (let k = i; k < j; ++k) {
7+
f[i][j] = Math.min(f[i][j], k + Math.max(f[i][k - 1], f[k + 1][j]));
8+
}
9+
}
10+
}
11+
return f[1][n];
12+
}

0 commit comments

Comments
 (0)