最大连续子序列和

214 阅读1分钟

问题描述

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。

题解

一道动态规划问题

定义状态:定义子问题

dp[i]: 表示nums中,以nums[i]为结尾的最大连续子序列和

状态转移方程:描述子问题之间的联系,需分类讨论

dp[i]={dp[i1]+nums[i], if dp[i1]>0nums[i], if dp[i1]0d p[i]=\left\{\begin{array}{lll} d p[i-1]+\operatorname{nums}[i], & \text { if } & d p[i-1]>0 \\ n u m s[i], & \text { if } & d p[i-1] \leq 0 \end{array}\right.

因为求子问题的最大值,所以可以写成如下形式:

dp[i] = Math.max(dp[i-1]+nums[i],nums[i]);

求动态规划的问题经常需要分类讨论(不同条件下的状态转移,取最优的)。

这是因为动态规划的问题本来就有「最优子结构」的特点。 即大问题的最优解通常由小问题的最优解得到,因此在设计子问题时,需要求解出所有子问题的结果,进而选出原问题的最优解。子问题最优解推出大问题最优解。

代码

public static int dp(int[] nums) {
    int[] dp = new int[nums.length];
    dp[0] = nums[0];
    int max = nums[0];
    for (int i = 1; i < nums.length; i++) {
        // 以每个位置为终点的最大子数列 都是基于其前一位置的最大子数列计算得出(基于前一位置的最优值)
        dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
        max = Math.max(dp[i], max);
    }
    return max;
}