动态规划:最大子数组和

最大子数组和

题干:

给定一个数组nums[],求下标连续的子数组的和的最大值,nums[i]表示第i个元素的数值,可以为负数,i从0开始递增。

nums = [-2,1,-3,4,-1,2,1,-5,4]

解题思路:

化大问题为小问题,通过局部最优解来推出全局最优解。

定义最佳状态数组: dp = [],dp[i]表示到第个元素为止,下标连续的子数组的和的最大值。

定义下标连续的子数组的和的最大值: maxVal,即存放最终答案。因为最大值不一定是dp最后一项。

请添加图片描述

题目分析:

如果数组长度为1

那么子元素长度也只能为1,最大子数组和为 第一个元素的值,此时dp[0]=nums[1];maxVal=nums[1]

最终为:dp[0]=-2; maxVal=-2

如果数组长度为2

前面已经算出了长度为1的数组的最大子数组和为dp[0],那么子数组和有两种情况,要么加上前面最大和dp[0],要么不加。最终加与不加取决于那种方式获得的值是最大的。

情况:

  1. 加。那么长度为2时子数组和最大值为:dp[0]+nums[1]=-2+1=-1
  2. 不加。那么长度为2时子数组和最大值为:nums[1]=1=1

取两者最大,得到至第2个元素为止,最大和为:dp[1] = max(-1,1) =1

算出最终的最大值,maxVal=max(dp[1],maxVal)= 1

如果数组长度为3

前面已经算出了长度为2的数组的最大子数组和为dp[1],那么最大子数组和有两种情况,要么加上前面最大和dp[0],要么不加。最终加与不加取决于那种方式获得的值是最大的。

情况:

  1. 加。那么长度为3是时,子数组和最大值为:dp[1]+nums[2]= 1 + -3 = -2
  2. 不加。那么长度为3时,子数组和最大值为:nums[2]=-3

取两者最大,得到至第3个元素为止,最大和为:dp[2] = max(-2,-3) = -2

算出最终的最大值,maxVal=max(dp[2],maxVal) = max(-2,1)= 1

如果数组长度为n

前面已经算出了长度为n的数组的最大子数组和为dp[n-1],那么最大子数组和有两种情况,要么加上前面最大和dp[n-1],要么不加。最终加与不加取决于那种方式获得的值是最大的。

情况:

  1. 加。那么长度为n是时,子数组和最大值为:dp[n-1]+nums[n]
  2. 不加。那么长度为n时,子数组和最大值为:nums[n]

取两者最大,得到至第n个元素为止,最大和为:dp[n] = max(dp[n-1]+nums[n],nums[n])

算出最终的最大值,maxVal=max(dp[n-1],maxVal)

代码编写

function maxSubArray(){
    /* 给定一个数组nums,求连续的最大的子数组的和为多少*/ 
    let nums = [-2,1,-3,4,-1,2,1,-5,4]
    // 定义初始状态 dp dp[i]为第i为最大的子数组和
    let dp = [nums[0]]
    // 状态转移方程 dp[i] = max(dp[i-1]+nums[i], nums[i]),前面最大和加上当前这个数的结果于当前这数比大小
    let maxVal = nums[0]
    for(let i=1;i<nums.length;i++){
        dp[i] = max(dp[i-1]+nums[i],nums[i])
        maxVal = max(dp[i], maxVal)
    }
    console.dir(dp)
    return "最大子数组和为:"+maxVal+"\n"
}
/*
 结果为: 6 ([4,-1,2,1])
*/
function max(a,b){
    return a > b ? a : b
}

结语:

动态规划的解题思路就是化大问题为小问题。像此题,先求出1个元素时的最优解,通过第一个最优解去推出2个元素时的最优解,通过第二个最优解继续推出3个元素时的最优解。直到第n个。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jayLog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值