0601-2020-LEETCODE-经典.46把数字翻译成字符串-经典.47礼物的最大价值(经典的DP问题)

一开始自己想用DFS,死活想不出来,最后看评论可以用DP,今天的两道题都是用dp解的,一定要多注意想不出来的时候,特别是数组字符串问题,多用dp。
评论链接:https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/comments/

	public int translateNum(int num) {
        if (num <= 9) return 1;
        char[] arr = String.valueOf(num).toCharArray();
        int len = arr.length;
        int[] nums = new int[len];
        for (int i = 0;i < len;i++){
            nums[i] = arr[i] - 48;
        }
        int[] dp = new int[len + 1];
        dp[0] = 1;
        dp[1] = 1;
        for (int i = 2; i < len + 1; i++) {
            if (nums[i - 2] != 0 && (nums[i - 2] * 10 + nums[i - 1]) <= 25){
                dp[i] = dp[i - 1] + dp[i - 2];
            } else {
                dp[i] = dp[i - 1];
            }
        }
        return dp[len];
    }

复习了一下这个数字翻译字符串。

public int maxValue1(int[][] grid) {
        int row = grid.length;
        int col = grid[0].length;
        int[][] dp = new int[row][col];
        int sum1 = 0;
        for (int i = 0; i < row; i++) {
            sum1 += grid[i][0];
            dp[i][0] = sum1;
        }
        int sum2 = 0;
        for (int i = 0; i < col; i++) {
            sum2 += grid[0][i];
            dp[0][i] = sum2;
        }
        for (int i = 1; i < row; i++) {
            for (int j = 1; j < col; j++) {
                dp[i][j] = Math.max(dp[i - 1][j],dp[i][j - 1]) + grid[i][j];
            }
        }
        return dp[row - 1][col - 1];
    }

最后为了优化原来的空间复杂度,可以原地修改数组。因为前面使用过的数组对后面的的计算结果没有影响。
代码思想来源:
https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/solution/mian-shi-ti-47-li-wu-de-zui-da-jie-zhi-dong-tai-gu/

	public int maxValue(int[][] grid) {
        int row = grid.length;
        int col = grid[0].length;
        for (int i = 1; i < row; i++) {
            grid[i][0] += grid[i - 1][0];
        }
        for (int i = 1; i < col; i++) {
            grid[0][i] += grid[0][i - 1];
        }
        for (int i = 1; i < row; i++) {
            for (int j = 1; j < col; j++) {
                grid[i][j] = Math.max(grid[i - 1][j],grid[i][j - 1]) + grid[i][j];
            }
        }
        return grid[row - 1][col - 1];
    }

再贴一个dfs 加 剪枝 操作的代码,需要用到一个缓存数组,用来表示当前的位置已经被计算过,结果就原地修改即可,代码的效率似乎要比dp还要好(也可能是lc的服务器的问题)。
作者:yang-li-gang
链接:https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/solution/dfsjia-jian-zhi-by-yang-li-gang/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

	public int maxValue(int[][] grid) {
        if (grid.length == 0) {
            return 0;
        }

        int[][] cache = new int[grid.length][grid[0].length];

        for(int i=0;i<grid.length;i++) {
            for(int j=0;j<grid[0].length;j++) {
                cache[i][j]=-1;
            }
        }

        return dfs(grid, 0, 0, cache);
    }

    private int dfs(int[][] grid, int row, int col, int[][] cache) {
        if (cache[row][col] != -1) {
            return cache[row][col];
        }

        int val = grid[row][col];

        int mr = row + 1;
        int downVal = 0;
        if (mr <= grid.length - 1) {
            downVal = dfs(grid, mr, col, cache);
        }

        int mc = col + 1;
        int rightVal = 0;
        if (mc <= grid[0].length - 1) {
            rightVal = dfs(grid, row, mc, cache);
        }

        val = val + Math.max(downVal, rightVal);
        cache[row][col] = val;
        return val;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值