Skip to content

Commit 656d42b

Browse files
committed
feat: add solutions to lcof problem: No.47
1 parent 3701915 commit 656d42b

File tree

9 files changed

+103
-111
lines changed

9 files changed

+103
-111
lines changed

lcof/面试题46. 把数字翻译成字符串/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
函数 $dfs(i)$ 的计算如下:
3636

3737
- 如果 $i \ge n - 1$,说明已经翻译到最后一个数字,只有一种翻译方法,返回 $1$;
38-
- 否则,我们可以选择翻译第 $i$ 个数字,此时翻译方法数目为 $dfs(i + 1)$;如果第 $i$ 个数字和第 $i + 1$ 个数字可以组成一个有效的字符(即 $s[i] == 1$ 或者 $s[i] == 2$ 且 $s[i + 1] \lt 6$),那么我们还可以选择翻译第 $i$ 和第 $i + 1$ 个数字,此时翻译方法数目为 $dfs(i + 2)$。因此$dfs(i)=dfs(i+1)+dfs(i+2)$。
38+
- 否则,我们可以选择翻译第 $i$ 个数字,此时翻译方法数目为 $dfs(i + 1)$;如果第 $i$ 个数字和第 $i + 1$ 个数字可以组成一个有效的字符(即 $s[i] == 1$ 或者 $s[i] == 2$ 且 $s[i + 1] \lt 6$),那么我们还可以选择翻译第 $i$ 和第 $i + 1$ 个数字,此时翻译方法数目为 $dfs(i + 2)$。因此 $dfs(i) = dfs(i+1) + dfs(i+2)$。
3939

4040
过程中我们可以使用记忆化搜索,将已经计算过的 $dfs(i)$ 的值存储起来,避免重复计算。
4141

@@ -47,7 +47,7 @@
4747

4848
定义 $f[i]$ 表示前 $i$ 个数字的不同翻译的数目,那么答案就是 $f[n]$。初始化 $f[0] = 1$, $f[1] = 1$。
4949

50-
我们可以从前往后计算 $f[i]$ 的值,对于每个 $i$,我们可以选择翻译第 $i$ 个数字,此时翻译方法数目为 $f[i - 1]$;如果第 $i-1$ 个数字和第 $i$ 个数字可以组成一个有效的字符(即 $s[i - 1] == 1$ 或者 $s[i - 1] == 2$ 且 $s[i] \lt 6$),那么我们还可以选择翻译第 $i - 1$ 和第 $i$ 个数字,此时翻译方法数目为 $f[i - 2]$。因此$f[i]=f[i-1]+f[i-2]$。
50+
我们可以从前往后计算 $f[i]$ 的值,对于每个 $i$,我们可以选择翻译第 $i$ 个数字,此时翻译方法数目为 $f[i - 1]$;如果第 $i-1$ 个数字和第 $i$ 个数字可以组成一个有效的字符(即 $s[i - 1] == 1$ 或者 $s[i - 1] == 2$ 且 $s[i] \lt 6$),那么我们还可以选择翻译第 $i - 1$ 和第 $i$ 个数字,此时翻译方法数目为 $f[i - 2]$。因此 $f[i] = f[i-1] + f[i-2]$。
5151

5252
由于 $f[i]$ 只与 $f[i - 1]$ 和 $f[i - 2]$ 有关,因此我们可以只用两个变量来存储 $f[i - 1]$ 和 $f[i - 2]$ 的值,从而省去数组 $f$ 的空间。
5353

lcof/面试题47. 礼物的最大价值/README.md

Lines changed: 58 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,17 @@
2828

2929
## 解法
3030

31-
动态规划法。
31+
**方法一:动态规划**
3232

33-
我们假设 `dp[i][j]` 表示走到格子 `(i, j)` 的礼物最大累计价值,则 `dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1]`
33+
我们定义 $f[i][j]$ 为从棋盘左上角走到 $(i-1, j-1)$ 的礼物最大累计价值,那么 $f[i][j]$ 的值由 $f[i-1][j]$ 和 $f[i][j-1]$ 决定,即从上方格子和左方格子走过来的两个方案中选择一个价值较大的方案。因此我们可以写出动态规划转移方程:
34+
35+
$$
36+
f[i][j] = max(f[i-1][j], f[i][j-1]) + grid[i-1][j-1]
37+
$$
38+
39+
答案为 $f[m][n]$。
40+
41+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为棋盘的行数和列数。
3442

3543
<!-- tabs:start -->
3644

@@ -40,11 +48,11 @@
4048
class Solution:
4149
def maxValue(self, grid: List[List[int]]) -> int:
4250
m, n = len(grid), len(grid[0])
43-
dp = [[0] * (n + 1) for _ in range(m + 1)]
44-
for i in range(1, m + 1):
45-
for j in range(1, n + 1):
46-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1]
47-
return dp[m][n]
51+
f = [[0] * (n + 1) for _ in range(m + 1)]
52+
for i, row in enumerate(grid, 1):
53+
for j, v in enumerate(row, 1):
54+
f[i][j] = max(f[i - 1][j], f[i][j - 1]) + v
55+
return f[m][n]
4856
```
4957

5058
### **Java**
@@ -53,13 +61,13 @@ class Solution:
5361
class Solution {
5462
public int maxValue(int[][] grid) {
5563
int m = grid.length, n = grid[0].length;
56-
int[][] dp = new int[m + 1][n + 1];
64+
int[][] f = new int[m + 1][n + 1];
5765
for (int i = 1; i <= m; ++i) {
5866
for (int j = 1; j <= n; ++j) {
59-
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
67+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]) + grid[i - 1][j - 1];
6068
}
6169
}
62-
return dp[m][n];
70+
return f[m][n];
6371
}
6472
}
6573
```
@@ -71,17 +79,42 @@ class Solution {
7179
public:
7280
int maxValue(vector<vector<int>>& grid) {
7381
int m = grid.size(), n = grid[0].size();
74-
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
75-
for (int i = 1; i < m + 1; ++i) {
76-
for (int j = 1; j < n + 1; ++j) {
77-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
82+
vector<vector<int>> f(m + 1, vector<int>(n + 1, 0));
83+
for (int i = 1; i <= m; ++i) {
84+
for (int j = 1; j <= n; ++j) {
85+
f[i][j] = max(f[i - 1][j], f[i][j - 1]) + grid[i - 1][j - 1];
7886
}
7987
}
80-
return dp[m][n];
88+
return f[m][n];
8189
}
8290
};
8391
```
8492
93+
### **Go**
94+
95+
```go
96+
func maxValue(grid [][]int) int {
97+
m, n := len(grid), len(grid[0])
98+
f := make([][]int, m+1)
99+
for i := range f {
100+
f[i] = make([]int, n+1)
101+
}
102+
for i := 1; i <= m; i++ {
103+
for j := 1; j <= n; j++ {
104+
f[i][j] = max(f[i-1][j], f[i][j-1]) + grid[i-1][j-1]
105+
}
106+
}
107+
return f[m][n]
108+
}
109+
110+
func max(a, b int) int {
111+
if a > b {
112+
return a
113+
}
114+
return b
115+
}
116+
```
117+
85118
### **JavaScript**
86119

87120
```js
@@ -106,49 +139,19 @@ var maxValue = function (grid) {
106139
};
107140
```
108141

109-
### **Go**
110-
111-
```go
112-
func maxValue(grid [][]int) int {
113-
m, n := len(grid), len(grid[0])
114-
dp := make([][]int, m + 1)
115-
for i := 0; i < m + 1; i++ {
116-
dp[i] = make([]int, n + 1)
117-
}
118-
for i := 1; i < m + 1; i++ {
119-
for j := 1; j < n + 1; j++ {
120-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1]
121-
}
122-
}
123-
return dp[m][n]
124-
}
125-
126-
func max(a, b int) int {
127-
if (a > b) {
128-
return a
129-
}
130-
return b
131-
}
132-
```
133-
134142
### **TypeScript**
135143

136144
```ts
137145
function maxValue(grid: number[][]): number {
138-
let n = grid.length;
139-
let m = grid[0].length;
140-
for (let i = 1; i < n; i++) {
141-
grid[i][0] += grid[i - 1][0];
142-
}
143-
for (let i = 1; i < m; i++) {
144-
grid[0][i] += grid[0][i - 1];
145-
}
146-
for (let i = 1; i < n; i++) {
147-
for (let j = 1; j < m; j++) {
148-
grid[i][j] += Math.max(grid[i][j - 1], grid[i - 1][j]);
146+
const m = grid.length;
147+
const n = grid[0].length;
148+
const f = Array.from({ length: m + 1 }, _ => new Array(n + 1).fill(0));
149+
for (let i = 1; i <= m; ++i) {
150+
for (let j = 1; j <= n; ++j) {
151+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]) + grid[i - 1][j - 1];
149152
}
150153
}
151-
return grid[n - 1][m - 1];
154+
return f[m][n];
152155
}
153156
```
154157

@@ -181,14 +184,13 @@ impl Solution {
181184
public class Solution {
182185
public int MaxValue(int[][] grid) {
183186
int m = grid.Length, n = grid[0].Length;
184-
int[,] dp = new int[m+1,n+1];
187+
int[, ] f = new int[m + 1, n + 1];
185188
for (int i = 1; i < m + 1; i++) {
186189
for (int j = 1; j < n + 1; j++) {
187-
dp[i,j] = Math.Max(dp[i-1,j], dp[i,j-1]) + grid[i-1][j-1];
190+
f[i, j] = Math.Max(f[i - 1, j], f[i, j - 1]) + grid[i - 1][j - 1];
188191
}
189192
}
190-
return dp[m,n];
191-
193+
return f[m, n];
192194
}
193195
}
194196
```

lcof/面试题47. 礼物的最大价值/Solution.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ class Solution {
22
public:
33
int maxValue(vector<vector<int>>& grid) {
44
int m = grid.size(), n = grid[0].size();
5-
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
6-
for (int i = 1; i < m + 1; ++i) {
7-
for (int j = 1; j < n + 1; ++j) {
8-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
5+
vector<vector<int>> f(m + 1, vector<int>(n + 1, 0));
6+
for (int i = 1; i <= m; ++i) {
7+
for (int j = 1; j <= n; ++j) {
8+
f[i][j] = max(f[i - 1][j], f[i][j - 1]) + grid[i - 1][j - 1];
99
}
1010
}
11-
return dp[m][n];
11+
return f[m][n];
1212
}
1313
};
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
public class Solution {
22
public int MaxValue(int[][] grid) {
33
int m = grid.Length, n = grid[0].Length;
4-
int[,] dp = new int[m+1,n+1];
4+
int[, ] f = new int[m + 1, n + 1];
55
for (int i = 1; i < m + 1; i++) {
66
for (int j = 1; j < n + 1; j++) {
7-
dp[i,j] = Math.Max(dp[i-1,j], dp[i,j-1]) + grid[i-1][j-1];
7+
f[i, j] = Math.Max(f[i - 1, j], f[i, j - 1]) + grid[i - 1][j - 1];
88
}
99
}
10-
return dp[m,n];
11-
10+
return f[m, n];
1211
}
1312
}
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
func maxValue(grid [][]int) int {
2-
m, n := len(grid), len(grid[0])
3-
dp := make([][]int, m + 1)
4-
for i := 0; i < m + 1; i++ {
5-
dp[i] = make([]int, n + 1)
6-
}
7-
for i := 1; i < m + 1; i++ {
8-
for j := 1; j < n + 1; j++ {
9-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1]
10-
}
11-
}
12-
return dp[m][n]
2+
m, n := len(grid), len(grid[0])
3+
f := make([][]int, m+1)
4+
for i := range f {
5+
f[i] = make([]int, n+1)
6+
}
7+
for i := 1; i <= m; i++ {
8+
for j := 1; j <= n; j++ {
9+
f[i][j] = max(f[i-1][j], f[i][j-1]) + grid[i-1][j-1]
10+
}
11+
}
12+
return f[m][n]
1313
}
1414

1515
func max(a, b int) int {
16-
if (a > b) {
17-
return a
18-
}
19-
return b
16+
if a > b {
17+
return a
18+
}
19+
return b
2020
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
class Solution {
22
public int maxValue(int[][] grid) {
33
int m = grid.length, n = grid[0].length;
4-
int[][] dp = new int[m + 1][n + 1];
4+
int[][] f = new int[m + 1][n + 1];
55
for (int i = 1; i <= m; ++i) {
66
for (int j = 1; j <= n; ++j) {
7-
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
7+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]) + grid[i - 1][j - 1];
88
}
99
}
10-
return dp[m][n];
10+
return f[m][n];
1111
}
1212
}

lcof/面试题47. 礼物的最大价值/Solution.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@
55
var maxValue = function (grid) {
66
const m = grid.length;
77
const n = grid[0].length;
8-
let dp = new Array(m + 1);
9-
for (let i = 0; i < m + 1; ++i) {
10-
dp[i] = new Array(n + 1).fill(0);
11-
}
12-
for (let i = 1; i < m + 1; ++i) {
13-
for (let j = 1; j < n + 1; ++j) {
14-
dp[i][j] =
15-
Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
8+
const f = Array.from({ length: m + 1 }, _ => new Array(n + 1).fill(0));
9+
for (let i = 1; i <= m; ++i) {
10+
for (let j = 1; j <= n; ++j) {
11+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]) + grid[i - 1][j - 1];
1612
}
1713
}
18-
return dp[m][n];
14+
return f[m][n];
1915
};
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
class Solution:
22
def maxValue(self, grid: List[List[int]]) -> int:
33
m, n = len(grid), len(grid[0])
4-
dp = [[0] * (n + 1) for _ in range(m + 1)]
5-
for i in range(1, m + 1):
6-
for j in range(1, n + 1):
7-
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1]
8-
return dp[m][n]
4+
f = [[0] * (n + 1) for _ in range(m + 1)]
5+
for i, row in enumerate(grid, 1):
6+
for j, v in enumerate(row, 1):
7+
f[i][j] = max(f[i - 1][j], f[i][j - 1]) + v
8+
return f[m][n]
Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
function maxValue(grid: number[][]): number {
2-
let n = grid.length;
3-
let m = grid[0].length;
4-
for (let i = 1; i < n; i++) {
5-
grid[i][0] += grid[i - 1][0];
6-
}
7-
for (let i = 1; i < m; i++) {
8-
grid[0][i] += grid[0][i - 1];
9-
}
10-
for (let i = 1; i < n; i++) {
11-
for (let j = 1; j < m; j++) {
12-
grid[i][j] += Math.max(grid[i][j - 1], grid[i - 1][j]);
2+
const m = grid.length;
3+
const n = grid[0].length;
4+
const f = Array.from({ length: m + 1 }, _ => new Array(n + 1).fill(0));
5+
for (let i = 1; i <= m; ++i) {
6+
for (let j = 1; j <= n; ++j) {
7+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]) + grid[i - 1][j - 1];
138
}
149
}
15-
return grid[n - 1][m - 1];
10+
return f[m][n];
1611
}

0 commit comments

Comments
 (0)