算法-动态规划-连续子数组的最大和

261 阅读2分钟

题目描述

nums = [-2,1,-3,4,-1,2,1,-5,4],连续子数组 [4,-1,2,1] 的和最大,为 6。。

解题思路

        这道题网上的解法有很多,这里介绍一下动态规划的解法,首先我们应该思考这道题可不可以使用动态规划来做?
动态规划解决的问题是多阶段决策最优模型,也可以理解成全局最优。一个问题的解决过程,对应着多个决策阶段,每一个决策阶段都对应着一组状态。我们要做的就是寻找一组决策序列,最终产生期望的最优解。
这里隐含着使用动态规划的几个条件
最优子结构:最终的最优解,可以通过子结构的最优解推导出来。
无后效性:我们关注的问题是状态。状态一旦确定了,就不受后续决策阶段的影响。

分析

  我们分析一下这道题,全局最优解是序列子数组的最大和,但是这里我们可以把这道题进行一个拆分:
1.求以arr[i]结尾的序列子数组最大和组成的数组dp
2.数组dp中求最大值
这样我们就可以得到一个dp方程:dp[n] = Max(dp[n - 1] + arr[n], arr[n]);(这道题的难点就在于这里,需要进行一个转换)

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

  这里使用了一个tmp变量,代替了图解中的dp数组,节省了一部分存储空间。

public int FindGreatestSumOfSubArray(int[] nums) {
    if (nums == null || nums.length == 0)
        return 0;
    ///先设置一个最小值
    int greatestSum = Integer.MIN_VALUE;
    ///求和
    int sum = 0;
    for (int val : nums) {
        ///sum可以看做临时数字之和
        sum = sum <= 0 ? val : sum + val;
        greatestSum = Math.max(greatestSum, sum);
    }
    return greatestSum;
}

xiaozhuanlan.com/topic/05831…

cloud.tencent.com/developer/a…