列表

详情


剑指 Offer 47. 礼物的最大价值

在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

 

示例 1:

输入: 
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int maxValue(vector<vector<int>>& grid) { } };

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]

上一题