剑指offer28--最大连续子数组的和

题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)

根据题目的复杂度的要求我们就可以看出来,也就是只能遍历一遍,所以只能使用遍历一遍的思路来写
思路如下:
例如输入的数组为{1, -2, 3, 10, -4, 7, 2, -5},和最大的子数组为{3, 10, -4, 7, 2}。因此输出为该子数组的和18 。

我们试着从头到尾逐个累加示例数组中的每个数字。初始化和为0。第一步加上第一个数字1, 此时和为1。接下来第二步加上数字-2,和就变成了-1。第三步刷上数字3。我们注意到由于此前累计的和是-1 ,小于0,那如果用-1 加上3 ,得到的和是2 , 比3 本身还小。也就是说从第一个数字开始的子数组的和会小于从第三个数字开始的子数组的和。因此我们不用考虑从第一个数字开始的子数组,之前累计的和也被抛弃。

我们从第三个数字重新开始累加,此时得到的和是3 。接下来第四步加10,得到和为13 。第五步加上-4, 和为9。我们发现由于-4 是一个负数,因此累加-4 之后得到的和比原来的和还要小。因此我们要把之前得到的和13 保存下来,它有可能是最大的子数组的和。第六步加上数字.7,9 加7 的结果是16,此时和比之前最大的和13 还要大, 把最大的子数组的和由13更新为16。第七步加上2,累加得到的和为18,同时我们也要更新最大子数组的和。第八步加上最后一个数字-5,由于得到的和为13 ,小于此前最大的和18,因此最终最大的子数组的和为18 ,对应的子数组是{3, 10, -4, 7, 2}。

package 剑指offer;

public class Test31 {
	public static void main(String args[]){
	// 例如输入的数组为{1, -2, 3, 10, -4, 7, 2, -5}
	// 和最大的子数组为{3, 10, -4, 7, 2}。因此输出为该子数组的和18 。
		
		int num[] = new int[]{1, -2, 3, 10, -4, 7, 2, -5};
		int max= findMaxNumber(num);
		System.out.println();
		System.out.println("最大子数组和为:"+max);
	}
	public static int findMaxNumber(int []num){
		int maxNum = num[0];
		int tempMaxNum = num[0];
		
		int i = 1;
		while(i < num.length){
			tempMaxNum += num[i];
			
			if(tempMaxNum < 0){
				tempMaxNum = 0;
				i++;
				//System.out.print(maxNum+" ");
			}else if(tempMaxNum >= 0 && tempMaxNum > maxNum){
				//打印已将加上的元素
				System.out.print(num[i]+" ");
				maxNum = tempMaxNum;
				i++;
				//System.out.print(maxNum+" ");
				
				//加上的是负数,但是tempMaxNum不小于零的情况下,就是说还有扭转的希望
			}else if(tempMaxNum >= 0 && tempMaxNum < maxNum){
				
				// 这就保证最后一个数为负数时,不打印
				if(i != num.length - 1){
					System.out.print(num[i]+" ");
				}
				i++;
				//System.out.print(maxNum+" ");
			}
		}
		return maxNum;
	}
}

来点鸡汤喝:
不要被现实中的不足所迷惑,也不要让琐事缠身,我们便会拥有一个充满希望的光辉灿烂的未来
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值