连续子数组的最大和Java

目录

题目要求

实现思路

代码展示

代码讲解

总结


题目要求

在一个数组中,找到连续子数组的最大和。重点是1.连续 2.最大 3.。我们把它翻译成人话,举个例子:arr=[1, -2, 3, 1]。返回值:4。因为arr[2]+arr[3]有最大值4。

结果不是5,因为arr[0]+arr[2]+arr[3]并不连续。(另外,我们不需要返回是谁加谁才有最大值,作为剑指offer中比较简单的题,我们只需要返回最大和即可)


实现思路

我们需要用到当前和currentSum,前次和lastSum,最大和maxSum等变量,以及一个单层循环来辅助我们完成这个方法。让我们了解一下以上概念。

之前和:每次循环末把之前值更新为当前值。第一次循环没有之前和

当前和:若之前和非负,则说明当前值加之前和后至少不会小于当前值,那么当前和等于当前值加之前。否则说明相加只会更小,那就令当前和等于当前值(贪心算法)。另外,第一次循环时,当前和等于当前元素

最大和:拿最大和与当前和作比较,谁大谁成为本次的最大和。另外,第一次循环时最大和等于当前元素

我们现在用数组 [1, -2, 3, 1] 来理解这个实现思路。

第一次(当前值=1):当前和=1最大和=1没有前次和

第二次(当前值=-2):前次和=1,那么当前和=前次和1+当前值-2=-1最大和=1不变因为当前和-1<最大和1)。

第三次(当前值=3):由于前次和=-1<0,因此若让当前和=当前值3+前次和-1,结果一定小于当前值3。如果我们这样,虽然2>1使得最大和=2,但是我们没有得到真正的最大值3。因此当前和=当前值=3,不加上前次和。更新最大和=3(因为当前和3>最大和1)

第四次(当前值=1):前次和=3,那么当前和=前次和+当前值=4,更新最大和=4(因为当前和4>最大和3)

退出循环并返回最大和


代码展示

package advance.algorithm;

public class MaxSubArr {
	public static int solution1(int[] arr) {//beter algorithm
		int lastSum=-1,currentSum,maxSum = Integer.MIN_VALUE;
		for(int i=0;i<arr.length;i++) {
			if(lastSum<0)
				currentSum=arr[i];
			else
				currentSum=lastSum+arr[i];
			if(currentSum>maxSum)
				maxSum=currentSum;
			lastSum=currentSum;
		}
		return maxSum;
	}
//测试
	public static void main(String[] args) {
		int[] arr={8,1,-3,-3,-1,2,1,-5,4};
		System.out.println("max value="+solution1(arr));
	}
}

代码讲解

这里简单的讲一下。在solution1()方法中,lastSum初始化时被赋值为-1的原因是我们想要让循环第一次lastSum不参与加和,即模拟第一次循环没有lastSum的效果,而从第一次循环末把lastsum更新为currentSum。

max被设置为了Integer.MIN_VALUE......这又是什么呢?这其实是个常数,表示的是整数类型可以表示的最小数,是-2^31。大家相信也能看出把最大值设置成-2^31用意,就是这样不管循环第一次的元素有多小,max总是比他小,于是max可以被更新为该元素值。

其他代码逻辑在"实现思路"这一模块都讲过了,这里就不再赘述。


总结

其实这道题的解决思路有很多种,有暴力搜索(这个不推荐,不仅代码又臭又长,时间复杂度还是O(n^3)),有动态规划,有前缀和,还有分治算法。而我们这篇文章讲的贪心算法独树一帜。虽然很少人会想到,但也着实是一个非常优秀的方法,他的时间复杂度小于上面讲的大部分算法。

所以推荐大家使用该算法!

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值