剑指 Offer 47. 礼物的最大价值
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
示例 1:
输入:[ [1,3,1], [1,5,1], [4,2,1] ]
输出:12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物
提示:
0 < grid.length <= 200
0 < grid[0].length <= 200
原站题解
golang 解法, 执行用时: 16 ms, 内存消耗: 3.7 MB, 提交时间: 2023-03-08 09:21:57
func maxValue(grid [][]int) int { n := len(grid[0]) f := grid[0] for j := 1; j < n; j++ { f[j] += f[j-1] } for _, row := range grid[1:] { f[0] += row[0] for j := 1; j < n; j++ { f[j] = max(f[j-1], f[j]) + row[j] } } return f[n-1] } func max(a, b int) int { if a < b { return b }; return a }
java 解法, 执行用时: 2 ms, 内存消耗: 43.9 MB, 提交时间: 2023-03-08 09:21:36
class Solution { public int maxValue(int[][] grid) { int m = grid.length, n = grid[0].length; var f = grid[0]; // 这里没有拷贝,f 和 grid[0] 都持有同一段内存 for (int j = 1; j < n; ++j) f[j] += f[j - 1]; for (int i = 1; i < m; ++i) { f[0] += grid[i][0]; for (int j = 1; j < n; ++j) f[j] = Math.max(f[j - 1], f[j]) + grid[i][j]; } return f[n - 1]; } }
python3 解法, 执行用时: 52 ms, 内存消耗: 16.1 MB, 提交时间: 2023-03-08 09:21:12
class Solution: def maxValue(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) f = grid[0] # 这里没有拷贝,f 和 grid[0] 都持有同一段内存 for j in range(1, n): f[j] += f[j - 1] for i in range(1, m): f[0] += grid[i][0] for j in range(1, n): f[j] = max(f[j - 1], f[j]) + grid[i][j] return f[-1]
java 解法, 执行用时: 1 ms, 内存消耗: 43.9 MB, 提交时间: 2023-03-08 09:19:59
class Solution { private int[][] grid, memo; public int maxValue(int[][] grid) { this.grid = grid; int m = grid.length, n = grid[0].length; memo = new int[m][n]; return dfs(grid.length - 1, grid[0].length - 1); } private int dfs(int i, int j) { if (i < 0 || j < 0) return 0; if (memo[i][j] > 0) // grid[i][j] 都是正数,记忆化的 memo[i][j] 必然为正数 return memo[i][j]; return memo[i][j] = Math.max(dfs(i, j - 1), dfs(i - 1, j)) + grid[i][j]; } }
golang 解法, 执行用时: 12 ms, 内存消耗: 4.3 MB, 提交时间: 2023-03-08 09:19:36
// 记忆化搜索 func maxValue(grid [][]int) int { m, n := len(grid), len(grid[0]) memo := make([][]int, m) for i := range memo { memo[i] = make([]int, n) } var dfs func(int, int) int dfs = func(i, j int) int { if i < 0 || j < 0 { return 0 } p := &memo[i][j] if *p > 0 { // grid[i][j] 都是正数,记忆化的 memo[i][j] 必然为正数 return *p } *p = max(dfs(i, j-1), dfs(i-1, j)) + grid[i][j] return *p } return dfs(len(grid)-1, len(grid[0])-1) } func max(a, b int) int { if a < b { return b }; return a }
python3 解法, 执行用时: 60 ms, 内存消耗: 21.6 MB, 提交时间: 2023-03-08 09:18:54
# 记忆化搜索 class Solution: def maxValue(self, grid: List[List[int]]) -> int: @cache def dfs(i: int, j: int) -> int: if i < 0 or j < 0: return 0 return max(dfs(i, j - 1), dfs(i - 1, j)) + grid[i][j] return dfs(len(grid) - 1, len(grid[0]) - 1)
java 解法, 执行用时: 2 ms, 内存消耗: 43.8 MB, 提交时间: 2023-03-08 09:16:06
class Solution { public int maxValue(int[][] grid) { int m = grid.length, n = grid[0].length; int[][] f = new int[m + 1][n + 1]; for (int i = 1; i <= m; ++i) { for (int j = 1; j <= n; ++j) { f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]) + grid[i - 1][j - 1]; } } return f[m][n]; } }
golang 解法, 执行用时: 4 ms, 内存消耗: 3.7 MB, 提交时间: 2023-03-08 09:15:03
func maxValue(grid [][]int) int { m, n := len(grid), len(grid[0]) for i := 0; i < m; i++ { for j := 0; j < n; j++ { if i == 0 && j == 0 { continue } if i == 0 { grid[i][j] += grid[i][j-1] } else if j == 0 { grid[i][j] += grid[i-1][j] } else { grid[i][j] += max(grid[i][j-1], grid[i-1][j]) } } } return grid[m-1][n-1] } func max(x, y int) int { if x < y { return y }; return x }
python3 解法, 执行用时: 52 ms, 内存消耗: 16.3 MB, 提交时间: 2022-11-13 12:41:40
class Solution: def maxValue(self, grid: List[List[int]]) -> int: for i in range(len(grid)): for j in range(len(grid[0])): if i == 0 and j == 0: continue if i == 0: grid[i][j] += grid[i][j - 1] # 0行上 elif j == 0: grid[i][j] += grid[i - 1][j] # 0列上 else: grid[i][j] += max(grid[i][j - 1], grid[i - 1][j]) return grid[-1][-1]