分治策略求解最大子数组问题

问题描述:给定数组A,求解A的和最大的非空连续子数组,数组为空时返回0。

算法思想:记数组A为A[low,high],取中间值mid=low+(high-low)/2,将A分为[low,mid]和[mid+1,high]两个子数组A的最大子数组分布为有以下三种情况:

1.全部位于[low,mid];

2.全部位于[mid+1,high];

3.跨越两子数组,记为[i,j] 其中i<=mid<j;

对三种情况分别讨论

1、2递归调用,将两个子数组当做完整数组求解其最大子数组;

3.以A[mid]为起点,向左向右依次遍历,求的左边最大连续子数组和右边最大连续子数组,拼接起来即是该种情况下原数组最大子数组

取三种情况下的最大值,即为A的最大子数组。

算法java实现

public class maxSubArray {
	public static void main(String[] args) {
		int[] A=new int[] {3,9,-2,0,4,6,-2,-1,3,7};//给定一个数组
		//int[] A=new int[] {3,-1,9,-1};//给定一个数组
		System.out.println(maxSubArray(A,0,A.length-1));
	}
	
	/**
	 * 
	 * @param num
	 * @param low 左下标
	 * @param high 右下标
	 * @return maxSubArraySum
	 */

	public static int maxSubArray(int[] num,int low,int high) {
		if(low==high)	return 0;
		
		int mid=low+(high-low)/2;
		int maxLeftSum=maxSubArray(num,low,mid);//情况1
		int maxRightSum=maxSubArray(num,mid+1,high);//情况2
		
		
		int maxCrossLeftSum=num[mid];
		//从num[mid]向左遍历
		for(int i=mid-1;i>=low;i--) {
			if(maxCrossLeftSum+num[i]>maxCrossLeftSum)
				maxCrossLeftSum+=num[i];
			else
				break;
		}
		
		int maxCrossRightSum=num[mid+1];
		for(int i=mid+2;i<=high;i++) {
			if(maxCrossRightSum+num[i]>maxCrossRightSum)
				maxCrossRightSum+=num[i];
			else
				break;
		}
		
		int maxCrossSum=maxCrossLeftSum+maxCrossRightSum;//情况3
		
		return Math.max(Math.max(maxLeftSum,maxRightSum),maxCrossSum);
		
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值