剑指Offer+第31题+连续子数组的最大和+java

题目:

输入一个整型数组,数组里有正数也有负数,数组中一个或连续多个整数组成一个子数组,求所有子数组的和的最大值。要求时间复杂度为O(n)

思路:

1、数组累加

从头到尾逐个累加数组中的每个数字,当累加之和小于0时,从下一个元素开始累加,并通过一个变量保存最大和。

2、动态规划,循环

思路与1一样,假设f(i)为以第i个数字结尾的子数组的最大和,那么

f(i)=A[i], f(i-1)<=0

f(i)=f(i-1)+A[i],f(i-1)>0

初始状态:f(0)=A[0]

最后求max(f(i)).

3. 动态规划,递归

可以推出转态转移方程式:

a[j]=Max(a[j],a[j-1]+a[j]) 

a[j]表示的是前j项的最大和,只需要取当前元素和前j-1项的加上当前元素的较大的值即可。

代码:

package array;

public class Offer31 {
	
	private static boolean invalidInput = false;
	
	//方法1,数字累加
	public int findGreatestSumOfSubArray(int [] array){
		if(array == null || array.length <=0){
			invalidInput = true;
			return 0;
		}
		
		invalidInput = false;
		
		int maxSum = array[0];//最大的子数组和
		int curSum = array[0];//累加的子数组和
		
		for(int i = 1;i<array.length;i++){
			if(curSum<=0)
				curSum = array[i];
			else
				curSum += array[i];
			
			if(curSum>maxSum)
				maxSum = curSum;
		}
		return maxSum;
	}
	
	//方法2,动态规划
	public int findGreatestSumOfSubArray_2(int [] array){
		if(array == null || array.length <=0){
			invalidInput = true;
			return 0;
		}
		
		invalidInput = false;
		
		int [] curSum = new int[array.length];
		int maxSum = Integer.MIN_VALUE;//0x80000000
		curSum[0] = array[0];
		for(int i = 1;i<array.length;i++){
			if(curSum[i-1] <=0 )
				curSum[i] = array[i];
			else
				curSum[i] = curSum[i-1] + array[i];
			if(curSum[i]<curSum[0])
				curSum[i] = curSum[0];//对应测试案例数组全是负数,并且是这种{-1,-2,-3,-4,-5}没这句,输出-2
			if(curSum[i] >maxSum)
				maxSum = curSum[i];
		}
		return maxSum;
	}
	
	//方法3,递归
	public int findGreatestSumOfSubArray_3(int [] array){
		if(array == null || array.length <=0){
			invalidInput = true;
			return 0;
		}
		
		invalidInput = false;
		
		int max = Integer.MIN_VALUE;
		int sum = 0;
		for(int i = 0;i<array.length;i++){
			sum = Math.max(array[i], array[i]+sum);
			max = Math.max(sum, max);
		}
		return max;
	}
	
	public static void main(String[] args) {
		
		Offer31 of31 = new Offer31();
		
		//功能测试,1,输入的数组有正数也有负数
		int [] arr11 = {1,-2,3,10,-4,7,2,-5};
		//System.out.println(of31.findGreatestSumOfSubArray(arr11));
		//System.out.println(of31.findGreatestSumOfSubArray_2(arr11));
		System.out.println(of31.findGreatestSumOfSubArray_3(arr11));
		
		//功能测试,2,输入的数组全是正数
		int [] arr21 = {1,2,3,4,5};
		//System.out.println(of31.findGreatestSumOfSubArray(arr21));
		//System.out.println(of31.findGreatestSumOfSubArray_2(arr21));
		System.out.println(of31.findGreatestSumOfSubArray_3(arr21));
		
		//功能测试,3,输入的数组全是负数
		int [] arr31 = {-1,-2,-3,-4,-5};
		//System.out.println(of31.findGreatestSumOfSubArray(arr31));
		//System.out.println(of31.findGreatestSumOfSubArray_2(arr31));
		System.out.println(of31.findGreatestSumOfSubArray_3(arr31));
		
		//特殊输入测试,4,表述数组的指针为NULL
		int [] arr41 = null;
		//System.out.println(of31.findGreatestSumOfSubArray(arr41));
		//System.out.println(of31.findGreatestSumOfSubArray_2(arr41));
		System.out.println(of31.findGreatestSumOfSubArray_3(arr41));

	}

}

运行结果:

18
15
-1
0

猜你喜欢

转载自blog.csdn.net/Quantum_Dog/article/details/88062215