用动态规划算法求最大子序和
问题描述:
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
动态规划解析:
状态定义:设动态规划列表 dp,dp[i]代表以元素 nums[i]为结尾的连续子数组最大和。
为何定义最大和 dp[i]中必须包含元素 nums[i]:保证 dp[i]递推到 dp[i+1]的正确性;如果不包含 nums[i],递推时则不满足题目的连续子数组要求。
转移方程:若dp[i−1]≤0 ,说明 dp[i - 1]对 dp[i]产生负贡献,即 dp[i-1] + nums[i]还不如 nums[i]本身大。
当 dp[i - 1] >0 时:执行 dp[i] = dp[i-1] + nums[i];
当 dp[i - 1] ≤0 时:执行 dp[i]=nums[i] ;
初始状态:dp[0] = nums[0],即以 nums[0]结尾的连续子数组最大和为 nums[0] 。
返回值:返回 dp列表中的最大值,代表全局最大值。
复杂度分析:
时间复杂度 O(N): 线性遍历数组 nums 即可获得结果,使用 O(N) 时间。
空间复杂度 O(1): 使用常数大小的额外空间。
代码:
int maxSubArray(int* nums, int numsSize){
if (!nums || numsSize <= 0)
{
return -0x80000000;
}
int dp = nums[0];
int max = dp;
int i;
for (i = 1;i < numsSize;i ++)
{
if (dp < 0)
{
dp = nums[i];
}
else
{
dp = dp + nums[i];
}
if (max < dp)
{
max = dp;
}
}
return max;
}