【leetCode】Maximum subArray & 【剑指】礼物最大价值

参考资料:《剑指Offer》

53. Maximum Subarray
Given an integer array nums, find the subarray with the largest sum, and return its sum.

Example 1:

Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: The subarray [4,-1,2,1] has the largest sum 6.

思路:
计算 以nums[i]为结尾时的子串的 maxSum 作为 local optimum, 然后 对i=0,1,…,n-1, 取 local optimum的最大值即可。
那么 如何求 local optimum,即 以nums[i]为结尾时的子串的 maxSum, 呢?
答:分两种情况:1. nums[i] 自己做 subArray; 2. nums[i] 联合 nums[i-1]的最优解一起 做 subArray; 对这两种情况取最大即可。

class Solution {
    public int maxSubArray(int[] nums) {
        int dp=nums[0]; // dp[0]
        int ans=dp;
        for(int i=1;i<nums.length;i++)
        {
            dp = Math.max(nums[i],nums[i]+dp);
            ans = Math.max(ans,dp);
        }
        return ans;
    }
}

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

示例 1:

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/li-wu-de-zui-da-jie-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:很像二维的楼梯问题,
对于一般位置(i,j)而言,他可能从(i-1,j)或(i,j-1)来到这里。
dp[i][j]表示 从(0,0)到(i,j) 所获的最大收益。
注意:初始化dp表的第0行和第0列。

class Solution {
    public int maxValue(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;

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

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

空间压缩
一行一行地更新dp表


    public int maxValue(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;

        int[] dp = new int[n];
        dp[0]=grid[0][0];
        for(int i=1;i<n;i++)
        {
            dp[i] = grid[0][i]+dp[i-1];
        }

        for(int i=1;i<m;i++)
        {
            dp[0]=grid[i][0]+dp[0];
            for(int j=1;j<n;j++)
            {
             dp[j] = Math.max(dp[j-1],dp[j])+grid[i][j];
            }
        }
        return dp[n-1];
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值