子序列2.连续子数组的最大和

子数组,这个题一开始肯定想到用滑动窗口,但它的数组有负数,所以不知道往哪移动,只能用动态规划。
用f(i)表示以i结尾的最大和数组,则要找的就是max{f(i)},为什么不用f(i)表示0到i的最大和,因为没法用f(i-1)推出f(i),f(i-1)不一定包括num[i-1]。所以f(i)=max(num[i],num[i]+f(i-1));
因为它是连续的,所以一个for就够了,子序列一般是O(n2)
所以遍历的时候如果cur小于0,就舍弃cur并令它等于当前的arr[i]。大于0的话就cur加上当前数。最后如果cur大于max,就令max=cur

class Solution {
    public int maxSubArray(int[] nums) {
        if(nums==null || nums.length==0)return 0;
        int res=nums[0];
        int[] dp=new int[nums.length];
        dp[0]=nums[0];
        for(int i=1;i<nums.length;i++){
            dp[i]=Math.max(nums[i]+dp[i-1],nums[i]);
            res=Math.max(res,dp[i]);
        }
        return res;
    }
}

如果加上一个条件是我可以跳过一次的话。
则再加一个数组f[i]来表示以i结尾且到目前为止没有用这次机会的最大和,
dp[i]表示以i结尾使用过这次机会最大值,两者取一个最大值即可。
f[i]=max(d[i-1]+num[i],num[i])
dp[i]=max(dp[i-1]+nums[i],d[i-1]);

class Solution {
    public int maximumSum(int[] arr) {
        int[] f=new int[arr.length];
        int[] dp=new int[arr.length];
        int res=arr[0];
        f[0]=arr[0];
        dp[0]=-100000;
        for(int i=1;i<arr.length;i++){
            f[i]=Math.max(f[i-1]+arr[i],arr[i]);
            dp[i]=Math.max(dp[i-1]+arr[i],f[i-1]);
            res=Math.max(res,f[i]);
            res=Math.max(res,dp[i]);
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值