53.最大子序和
题目地址:https://leetcode-cn.com/problems/maximum-subarray/
给定一个整数数组nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组[4,-1,2,1] 的和最大为6。
那么该题贪心贪的是哪里呢?
如果 -2、1 在一起,计算起点的时候,一定是从1开始计算,因为负数只会拉低总和,这就是贪心贪的地方!
局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
全局最优:选取最大“连续和”。
局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
从代码角度上来讲:遍历nums,从头开始用count累积,如果count一旦加上nums[i]变为负数,那么就应该从nums[i+1]开始从0累积count了,因为已经变为负数的count,只会拖累总和。
这相当于是暴力解法中的不断调整最大子序和区间的起始位置。
那还有一个问题,区间终止位置不用调整么? 如何才能得到最大“连续和”呢?
区间的终止位置,其实就是如果count取到最大值了,及时记录下来了。
例如如下代码:
if (count > result) result = count;
这样相当于是用result记录最大子序和区间和(变相的算是调整了终止位置)。
如图所示:
红⾊方块的起始位置就是贪⼼每次取count为正数的时候,开始⼀个区间的统计。最后得出最大子序和结果。
java代码整体如下:
什么是贪心算法?
贪心的本质是选择每一个阶段的局部最优,从而达到全局最优。
举个例子:
假如钱包里有一堆钞票,你可以拿走5张,如果想要尽可能的拿到最大的金额,你要如何拿?
每次拿最大的,最终结果就是拿走最大的金额数。
每次拿最大的就是局部最优,最后拿走最大数额的钱就是推出全局最优。