算法——输出数组最大子序列和

今天看算法,看到一道题,题目描述如下:

给一个数组,找出该数组的最大子序列和。例如:数组{0,-1,-9,8,1,-8,10,-1},最大子序列为8+1-8+10=11,需要输出11。

由于很久没有写算法,遇见这个问题想了很久,大约花了一个半小时才想出来这个问题。

先贴一下代码:

package com.atguigu.java;

public class HelloWorld {
	public static void main(String[] args){
		int[]a={0,-1,-9,8,1,-8,10,-1};
		int sum=a[0];
		int max=a[0];
		int summax=0;
		int b=a.length;
		for(int i=1;i<b;i++)
		{
			if(a[i]>0)
			{		
				sum+=a[i];
			}
			if(a[i]<0)
			{	
				if(a[i-1]>=0)
				{
					max=sum;
				}
				else if(sum+a[i]<=0)
				{	
				sum=0;
				if(i==b-1)
					sum=a[i];
				}
				if(a[i]>max)
				{
					max=a[i];
					
				}
				if(sum+a[i]>0) 
					sum+=a[i];
			}
			if(i==b-1)
			{	
				if(max>sum)
					summax=max;
				else
					summax=sum;
			}
		}
		System.out.println(summax);
		
	}
	
}

输出结果如下:

解这道题的思路如下:

首先,这个数组中有正数也有负数,由于负数的存在,会使得某些子序列在加了负数之后小于零,这时,这个序列就没有价值了,可以重新开始一个新的序列。我们可以设置一个sum来装子序列的和,而max用来装最大的连续正数的和。最大连续正数的和可以在a[i]<0的前提下,通过判断a[i-1],即前一个元素是否为正数来达到目的。因为如果前一个元素为正数,而当前遍历到的元素为负数,那么之前的sum则是目前最大的正数序列的和。当数组遍历到最后一个元素的时候,sum与max进行比较,得出最大子序列的和。

上文中的这个算法的时间复杂度为O(n)。

这个问题还可以继续扩充,比如,在输出最大子序列的和的同时还需要输出对应的元素,即输出一个新的数组。这个也好办到,只需要添加一个新的数组,用来存放下标,每一次子序列更新都无需将该数组中的元素全部修改,只需要在修改下标的时候标记每个序列的个数,这样,找到最大子序列之后再依据标记输出数组相应个数的元素即可。

猜你喜欢

转载自blog.csdn.net/Searchin_R/article/details/82891827