最大子数组的递归实现和线性实现

public class MaxSubArray 
{
	public static void main(String[] args)
	{
		int[] array = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
		Result result = getMaxSubArrayNLogN(array, 0, array.length - 1);
		System.out.println(result.leftIndex);
		System.out.println(result.rightIndex);
		System.out.println(result.sum);
		
		Result result1 = getMaxSubArrayN(array);
		System.out.println(result1.leftIndex);
		System.out.println(result1.rightIndex);
		System.out.println(result1.sum);
	}

	public static Result getMaxSubArrayNLogN(int[] array, int start, int end)
	{
		if(start == end)
		{
			Result result = new Result();
			result.leftIndex = start;
			result.rightIndex = end;
			result.sum = array[start];
			return result;
		}
		
		int middle = (end - start)/2 + start;
		
		Result leftResult = getMaxSubArrayNLogN(array, start, middle);
		Result middleResult = getMaxCrossSubArray(array, start, end);
		Result rightResult = getMaxSubArrayNLogN(array, middle + 1, end);
		
		if(leftResult.sum > middleResult.sum)
		{
			if(leftResult.sum > rightResult.sum)
			{
				return leftResult;
			}
			else
			{
				return rightResult;
			}
		}
		else
		{
			if(middleResult.sum > rightResult.sum)
			{
				return middleResult;
			}
			else
			{
				return rightResult;
			}
		}
	}
	
	public static Result getMaxSubArrayN(int[] array)
	{
		Result result = new Result();		
		if(array.length == 1)
		{
			result.leftIndex = 0;
			result.rightIndex = 0;
			result.sum = array[0];
			
			return result;
		}
		
		int leftIndex = 0;
		int rightIndex = 0;
		int maxSum = array[0];
		for(int i = 1; i < array.length; i++)
		{
			if(array[i] <= 0)
			{
				continue;
			}
			
			int tmpMaxSum = Integer.MIN_VALUE;
			int tmpSum = 0;
			int tmpLeftIndex = 0;
			for(int j = i; j > rightIndex; j--)
			{
				tmpSum += array[j];
				if(tmpSum > tmpMaxSum)
				{
					tmpMaxSum = tmpSum;
					tmpLeftIndex = j;
				}
			}
			
			if(tmpSum < 0)
			{
				if(tmpMaxSum > maxSum)
				{
					leftIndex = tmpLeftIndex;
					rightIndex = i;
					maxSum = tmpMaxSum;
				}
			}
			else
			{
				rightIndex = i;
				maxSum += tmpSum;
			}
		}
		
		result.leftIndex = leftIndex;
		result.rightIndex = rightIndex;
		result.sum = maxSum;
		
		return result;
	}
	
	private static Result getMaxCrossSubArray(int[] array, int start, int end)
	{
		Result result = new Result();
		
		int middle = (end - start)/2 + start;
		
		int leftMaxNumber = Integer.MIN_VALUE;
		int leftSum = 0;
		int leftIndex = -1;
		int i = middle;
		while( i >= start)
		{
			leftSum += array[i];
			if(leftSum > leftMaxNumber)
			{
				leftMaxNumber = leftSum;
				leftIndex = i;
			}
			i--;
		}
		
		int rightMaxNumber = Integer.MIN_VALUE;
		int rightSum = 0;
		int rightIndex = -1;
		i = middle + 1;
		while( i <= end)
		{
			rightSum += array[i];
			if(rightSum > rightMaxNumber)
			{
				rightMaxNumber = rightSum;
				rightIndex = i;
			}
			i++;
		}
		
		result.leftIndex = leftIndex;
		result.rightIndex = rightIndex;
		result.sum = leftMaxNumber + rightMaxNumber;
		
		return result;
	}
	
	private static class Result
	{
		int leftIndex;
		int rightIndex;
		int sum;
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值