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

题目:

思路:

【1】碰到的时候最先想起的是深度优先和广度优先的遍历(后面发现了要用到辅助空间,那么用到辅助空间的话,其实还可以考虑动态规划)

【2】动态规划的方式(但其实这种相对更优,可能是由于空间换了时间)

代码展示:

动态规划的方式:

//时间2 ms击败97.82%
//内存43.8 MB击败89.68%
//时间复杂度 O(MN) : M,N 分别为矩阵行高、列宽;动态规划需遍历整个 grid 矩阵,使用 O(MN) 时间。
//空间复杂度 O(MN) : 开辟了等大小的额外空间。
class Solution {
    public int maxValue(int[][] grid) {
        int row = grid.length;
        int column = grid[0].length;
        //dp[i][j]表示从grid[0][0]到grid[i - 1][j - 1]时的最大价值
        int[][] dp = new int[row + 1][column + 1];
        for (int i = 1; i <= row; i++) {
            for (int j = 1; j <= column; j++) {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
            }
        }
        return dp[row][column];
    }
}

当然还存在不开辟额外空间
//时间2 ms击败97.82%
//内存43.8 MB击败88.31%
//时间复杂度 O(MN) : M,N 分别为矩阵行高、列宽;动态规划需遍历整个 grid 矩阵,使用 O(MN) 时间。
//空间复杂度 O(1) : 原地修改使用常数大小的额外空间。
class Solution {
    public int maxValue(int[][] grid) {
        int m = grid.length, n = grid[0].length;

        // 初始化第一行
        for(int j = 1; j < n; j++){
            grid[0][j] += grid[0][j - 1];
        }

        // 初始化第一列
        for(int i = 1; i < m; i++) {
            grid[i][0] += grid[i - 1][0];
        }

        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                grid[i][j] += Math.max(grid[i][j - 1], grid[i - 1][j]);
            }
        }

        return grid[m - 1][n - 1];
    }
}

 

深度优先遍历的方式:

//但是这种直接是超时,估计是出现数据庞大的时候,重复运算多了耗时比较多
class Solution {
    public int maxValue(int[][] grid) {
        if (grid == null || grid.length == 0){
            return 0;
        }
        return dfsmaxValue(grid,grid.length-1,grid[0].length-1);
    }

    //i为行,j为列,该方式为从终点反推回起点
    public int dfsmaxValue(int[][] grid,int i,int j){
        if (i < 0 || j < 0){
            return 0;
        }
        //向上走 与 向左走 之前取最大值
        return Math.max(dfsmaxValue(grid, i - 1, j), dfsmaxValue(grid, i, j - 1)) + grid[i][j];
    }
}

//开辟一块空间保存一下计算的值
//时间20 ms击败2.20%
//内存46.5 MB击败5.6%
class Solution {
    public int maxValue(int[][] grid) {
        if (grid == null || grid.length == 0){
            return 0;
        }
        return dfsmaxValue(grid,grid.length-1,grid[0].length-1, new HashMap<>());
    }

    //i为行,j为列,该方式为从终点反推回起点
    public int dfsmaxValue(int[][] grid,int i,int j, Map<String, Integer> map){
        if (i < 0 || j < 0){
            return 0;
        }

        String key = i + "*" + j;
        int res = map.getOrDefault(key, -1);

        //如果以前计算过,就从map中取
        if (res != -1){
            return res;
        }

        //如果之前没有计算过,则进行计算
        res = Math.max(dfsmaxValue(grid, i - 1, j, map), dfsmaxValue(grid, i, j - 1, map)) + grid[i][j];
        //把计算的结果还存到map中
        map.put(key, res);

        return res;
    }
}

 

posted @ 2023-02-01 17:45  忧愁的chafry  阅读(8)  评论(0编辑  收藏  举报