算法之最大子数组

本文介绍了一种求解最大子数组和的问题,通过分治法和线性实现法两种方式来解决。分治法利用递归将问题分解为较小的子问题,而线性实现法则采用动态规划思想,只需遍历一次数组即可找到最大子数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用了两种方式来实现,一种是递归的分治法,另一种非递归的线性法。

1)分治法

 

package com.cn.z.sort;
/**
 * 最大子数组
 *
 */
public class MaxChildArray {
	
	public Integer[] obtainMaxChildArray(Integer[] data,int low,int height){
		if(low==height){
			return new Integer[]{low,height,data[low]};
		}else{
			int mid=(low+height)/2;
			//求左半部分最大子数组
			Integer [] maxleft=this.obtainMaxChildArray(data, low, mid);
			//求右半部分最大子数组
			Integer[] maxright=this.obtainMaxChildArray(data, mid+1, height);
			//求跨部分的最大子数组
			Integer [] maxCrossMid=this.maxCrossMid(data, low, mid, height);
			//返回这三个里面最大的子数组
			Integer[] returnArray=maxright;
			if(maxleft[2]>maxright[2]){
				returnArray=maxleft;
			}
			if(returnArray[2]>maxCrossMid[2]){
				return returnArray;
			}else{
				return maxCrossMid;
			}
		}
	}
	
	public Integer[] maxChildArray(Integer[] data){
		int low=0;
		int height=data.length-1;
		return this.obtainMaxChildArray(data, low, height);
	}
	//求跨两部分的最大子数组
	public Integer[] maxCrossMid(Integer[] data,int low,int mid,int height){
		Integer maxLow=0;
		Integer maxheight=0;
		Integer lowLocation=0;
		Integer heightLocation=0;
		Integer sumLow=0;
		for(int i=mid;i>=low;i--){
			sumLow+=data[i];
			if(maxLow<sumLow){
				maxLow=sumLow;
				lowLocation=i;
			}
		}
		Integer sumHeight=0;
		for(int i=mid+1;i<=height;i++){
			sumHeight+=data[i];
			if(maxheight<sumHeight){
				maxheight=sumHeight;
				heightLocation=i;
			}
		}
		return new Integer[]{lowLocation,heightLocation,maxheight+maxLow};
	}
	
	public static void main(String[] args) {
		MaxChildArray test=new MaxChildArray();
		Integer[] data=new Integer[]{13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
		Integer[] results=test.maxChildArray(data);
		//开始位置
		System.out.println(results[0]);
		//结束位置
		System.out.println(results[1]);
		//和
		System.out.println(results[2]);
	}
}

 

2)、线性实现法

 

 

public class MaxChildArrayLinear {
	
	public Integer[] maxChildArray(Integer[] data){
		int low=0;
		int height=0;
		int sum=data[0];
		int boundSum=data[0];
		for(int i=1;i<data.length;i++){
			if(boundSum+data[i]>=data[i]){
				boundSum+=data[i];
			}else{
				low=i;
				boundSum=data[i];
			}
			if(sum<boundSum){
				sum=boundSum;
				height=i;
			}
		}
		return new Integer[]{low,height,sum};
	}
	
	public static void main(String[] args) {
		MaxChildArrayLinear test=new MaxChildArrayLinear();
		Integer[] data=new Integer[]{13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
		Integer[] results=test.maxChildArray(data);
		//开始位置
		System.out.println(results[0]);
		//结束位置
		System.out.println(results[1]);
		//和
		System.out.println(results[2]);
	}
}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值