最大子序列之和

用 f(i) 代表以第 i 个数结尾的「连续子数组的最大和」
如何求 f(i) 呢?我们可以考虑 nums[i] 单独成为一段还是加入 f(i-1)对应的那一段,这取决于 nums[i] 和 f(i−1)+nums[i] 的大小,我们希望获得一个比较大的,于是可以写出这样的动态规划转移方程:
状态转移方程: f(i) = max(f(i-1) + nums[i], nums[i])

java实现:

class Solution {
    public int maxSubArray(int[] nums) {
        int n = nums.length;
        if(n == 0) return 0;
        //定义dp数组,dp数组中的每个值dp[i]代表着以nums[i]为结尾的最大子序和
        int[] dp = new int[n];
        //以nums[0]结尾的最大子序和就是nums[0]
        dp[0] = nums[0];
        //遍历,通过状态转移方程求得dp[i]的最大子序和
        for(int i = 1; i < n; ++i){
            //dp[i]的最大子序和要么是自成一派最大,要么就是当前值加上前面i - 1个数的最大子序和
            //如果前边累加后还不如自己本身大,那就把前边的都扔掉,从此自己本身重新开始累加。
            dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]);
        }

        //遍历dp数组,求得dp数组中的最大值,就是该题的答案
        int res = Integer.MIN_VALUE;
        for(int j = 0; j < dp.length; ++j){
            res = Math.max(res, dp[j]);
        }
        return res;
    }
}

贪心思想:若当前指针所指元素之前的和小于0,则丢弃之前的数列
在这里插入图片描述

class Solution(object):
    def maxSubArray(self, nums):
       cur_sum=max_sum=nums[0]
       for i in range(1,len(nums)):
           cur_sum=max(nums[i],nums[i]+cur_sum)
           max_sum=max(max_sum,cur_sum)
       return max_sum
           
        """
        其实这里相当于是一个比较,
        比较了f(i-1)+nums[i]和nums[i]的大小,
        依次遍历后nums每个数字都变成了相应的f(i),
        即以第 i 个数结尾的「连续子数组的最大和」
        """
            nums[i]=max(nums[i],nums[i-1]+nums[i])
        return max(nums)

动态规划思想:若前一个元素大于0,则将其加到当前元素上
在这里插入图片描述

class Solution(object):
    def maxSubArray(self, nums):
        n=len(nums)
        for i in range(1,n):
        """
        其实这里相当于是一个比较,
        比较了f(i-1)+nums[i]和nums[i]的大小,
        依次遍历后nums每个数字都变成了相应的f(i),
        即以第 i 个数结尾的「连续子数组的最大和」
        """
            nums[i]=max(nums[i],nums[i-1]+nums[i])
        return max(nums)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值