java数据结构之子最大子数组和

Posted xxniuren

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java数据结构之子最大子数组和相关的知识,希望对你有一定的参考价值。

题:给定一个数组,其中当然有很多子数组,在所有两个子数组的组合中,找到相加和最大的一组,要求两个子数组无重合的部分,最后返回累加和。

1、解题思路

如果给一个数组为[ -1 -2 1 2 3 -4 -5 2 3 2 -1 -2],如果要得到其最大子数组和,那么我们可以遍历整个数组,找出该数组每一个元素的左边最大的子数组和,右边的最大子数组和,两个和相加,用一个全局变量maxResult保存最终得到的结果,遍历每一个元素,比较一次最大结果,整个数组遍历完后,那么可以得到最终的最大子数组和。

如何找到左边和右边最大子数组和,就拿左边数组求最大子数组来说,求解思路为:设定两个中间变量,sumData和maxData,对数组进行一次遍历,sumData=sumData+Array[i],如果sumData<0,那么把sumData归零,如果sumData>maxData,那么把maxData更新。画个图方便讲解:


上面给的代码做了三件事,1、从第一个数开始往后面做求和 (sumData);2、如果和为负数,那么把和(sumData)归零 ;3、把sumData和maxData进行比较,大于maxData时更新maxData。如果我的目标区域是从p1到p3区域内最大的子数组和的话,那么从p2往p1的求和都是负数,如果不是负数的话,那么p2-p3区域不是潜在最大的区域,因为还可以往p2左方向扩充。把sumData和maxData进行对比,是为了不丢掉最大的区域,对比所有潜在最大区域,然后存储所得最大区域。就拿数组[ -1 -2 1 2 3 -4 -5 2 3 2 -1 -2]来说,index=0,sumData=-1<0,则把sumData设置为0,maxData=0,;前三个sumData均为0,maxData也为0,这个好理解,如果我一个序列全为负数的话,那我最大的子序列和肯定是空,空集合为所有集合的子集。当index=3时,sumData=1,maxData=1;index=4时,sumData=3,maxData更新为3;index=5,时,sumData=6,maxData也更新为6;index=6时,sumData=2,此时maxData不做更新,还是6,这个应该好理解,就是在index=6之前的序列最大的子序列和为6,。同理可以得到在任何一个index的左边的最大子序列和,同时也可以得到右边的最大子序列和。这两个最大子序列和相加,则可以得到在一个index上的左边和右边最大子序列和之和。这个有点绕口,大家可以按照例子屡两遍思路则明白了。

2、具体实现代码

package TwoSubArrayMaxSum;

import java.util.Scanner;

public class TwoSubArrayMaxSum 
	//数组输入

	public int dataArray[];	//初始化数组,存放数据
	public int len;							//记录数组长度
	
	public TwoSubArrayMaxSum()				//得到输入数组
	    String s;   //
		String sbuf[];
		Scanner sc=new Scanner(System.in);
		s=sc.nextLine();
		sbuf=s.split(" ");
		len=sbuf.length;
		dataArray=new int[len];
		for(int i=0;i<len;i++)
			dataArray[i]=Integer.parseInt(sbuf[i]);
		
	
	//得到最大值
	public int GetTwoSubArrayMaxResult()
		int dataArrayBuff[]=new int[len];
		int maxResult=0;//最大值
		int maxData=0,sumData=0;
		for(int i = len-1;i >=0 ; i--)			//从右往左遍历,把最大的加和放到缓存数组里面
			sumData+=dataArray[i];
			sumData=(sumData<0)?0:sumData;      //判断sumData是否小于0  小于0则清零
			if(sumData>maxData)
				dataArrayBuff[i]=sumData;
				maxData=sumData;
			else
				dataArrayBuff[i]=maxData;
			
		
		//从左往右开始遍历取值,把最大的值放到变量里面
		sumData=0;
		maxData=0;
		for(int i=1;i<len-2;i++)
			sumData+=dataArray[i-1];			//达到自加数据
			sumData=(sumData<0)?0:sumData;		//查看数据是否小于0
			if(sumData>maxData)
				maxData=sumData;
			
			maxResult=(maxResult>(maxData+dataArrayBuff[i]))?maxResult:(maxData+dataArrayBuff[i]);
		
		return maxResult;
	
	
	public static void main(String[] args) 
		TwoSubArrayMaxSum t=new TwoSubArrayMaxSum();
		System.out.println(t.GetTwoSubArrayMaxResult());
	



程序说明:

TwoSubArrayMaxSum构造方法是为了得到输入数组。求解最大子数组和是由GetTwoSubArrayMaxResult方法实现。该过程首先是从右到左得到最大的子数组和,存放在dataArrayBuff里面,然后从左往右开始一次遍历,两个最大子数组和,存放到maxResult结果中,然后不同的index得到的最大子数组和进行比较,决策是否需要更新maxResult,这样完成在该数组上的所有可能性的查找。



以上是关于java数据结构之子最大子数组和的主要内容,如果未能解决你的问题,请参考以下文章

java数据结构之子最大子数组和

最大子数组之和

数组之求最大子数组之和

最大子数组之和 2

最大子数组之和首位相邻32位版

环形数组最大子数组之和