每日一练-----最大连续子数组的和

问题:

给定一个整数数组,数组种可能存在正数、负数和零。求所有子数组的和的最大值;

例如:

如果输入的数组是{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},

那么输出该子数组的和为18

思想:

解决方法类似于上面的求子数组最大积,只是当前位置处子数组的最大和可能是前面的max+当前位置值与当前位置值得最大值;

代码:

public class MaxSum {
	public static void main(String[] args) {
		int[] arr = {6,-3,-2,7,-15,1,2,2};
		System.out.println(getMaxSum(arr));
	}
	public static int getMaxSum(int[] arr)
	{
		if(arr == null)
			return -1;
		if(arr.length == 0)
			return 0;
		int max = arr[0];
		int result = arr[0];
		for(int i = 1;i < arr.length;i++)
		{
			max = max+arr[i];
			max = Math.max(max, arr[i]);
			result = Math.max(max, result);
		}
		return result;
	}
}

那么如果想要输出这个最大和的子数组的话,我们需要修改代码,只需要增加一个标志数组用来记录这个子数组的开始和结束位置即可了;

public class MaxSum {
	public static void main(String[] args) {
		int[] arr = {1,-2,3,10,-4,7,2,-5};
		int[] result = getMaxSumStartAndEnd(arr);
		if(result != null)
			print(arr, result[0], result[1]);
	}
	/**
	 * 获得子数组和最大的子数组的开始和结束下标
	 * @param arr
	 * @return
	 */
	public static int[] getMaxSumStartAndEnd(int[] arr)
	{
		int[] result = new int[2];
		int start = 0;//开始下标
		int end = 0;//结束下标
		if(arr == null)
			return null;
		if(arr.length == 0)
		{
			result[0] = 0;
			result[1] = 0;
			return result;
		}
		int max = arr[0];//临时最大值
		int tempMax = arr[0];//临时值
		int realMax = arr[0];//最后真正的最大值
		for(int i = 1;i < arr.length;i++)
		{
			tempMax = max+arr[i];
			max = Math.max(tempMax, arr[i]);
			if(max > realMax && max == tempMax)
			{
				//表示当前最大值是加上当前元素后得到的,那么就需要修改end下标值了
				end = i;
			}else if(max > realMax && max == arr[i])
			{
				//表示当前最大值是当前元素,那么需要修改start下标值
				start = i;
			}
			realMax = Math.max(max, realMax);
		}
		result[0] = start;
		result[1] = end;
		return result;
	}
	
	public static void print(int[] arr,int start,int end)
	{
		for(int i = start;i <= end;i++)
		{
			System.out.print(arr[i]+" ");
		}
	}
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值