一个有N个证书元素的以为数组,子数组之和的最大值是多少?
分析:
1子数组是连续的;
2题目只需要求和,不需要返回子数组具体位置;
3数组的元素是整数,所以数组可能包括正整数,零,负整数;
最直接的最简单的方法记sum[i....j]为数组第i个元素导第j个元素的和,遍历所有可能得,代码如下:
//最直接的遍历 public static int GetMaxSum(int[] input,int num){ int maxsum=Integer.MIN_VALUE; int sum=0; for(int i=0;i<num;i++){ sum=0; for(int j=i;j<num;j++){ sum+=input[i]; if(sum>maxsum){ maxsum=sum; } } } return maxsum; }
分治法:将所给数组分为相当的2个子数组,分别求出这两段子数组的最大和,则原数组的最大和子数组有以下3中情况:
1(A[0]....A[n-1])数组的最大子段与(A[0]....A[n/2-1])的最大子段相同;
2(A[0]....A[n-1])数组的最大子段与(A[n/2]....A[n-1])的最大子段相同;
3(A[0]....A[n-1])数组的最大子段跨过起中间两个元素A[n/2-1]与A[n/2];
算法复杂度O(NlogN)
1 public class MaxSum { 2 //分治法 3 public static int GetMaxSum(int[] input,int start,int end){ 4 if(start==end){ 5 return input[start]; 6 } 7 int maxleftbordersum=Integer.MIN_VALUE,maxrightbordersum=Integer.MIN_VALUE; 8 int maxcentersum; 9 int center=(start+end)/2; 10 int maxleftsum=GetMaxSum(input,start,center); 11 int maxrightsum=GetMaxSum(input,center+1,end); 12 int sum=0; 13 for(int i=center;i>=start;i--){ 14 sum+=input[i]; 15 if(sum>maxleftbordersum){ 16 maxleftbordersum=sum; 17 } 18 } 19 sum=0; 20 for(int i=center+1;i<=end;i++){ 21 sum+=input[i]; 22 if(sum>maxrightbordersum){ 23 maxrightbordersum=sum; 24 } 25 } 26 maxcentersum=maxleftbordersum+maxrightbordersum; 27 int max1= maxleftsum>maxrightsum?maxleftsum:maxrightsum; 28 return max1>maxcentersum?max1:maxcentersum; 29 } 30 //动态规划法 31 public static int GetMaxSum2(int[] input){ 32 int Start=input[input.length-1]; 33 int all=input[input.length-1]; 34 for(int i=input.length-2;i>=0;i--){ 35 Start=Math.max(input[i], Start+input[i]); 36 all=Math.max(Start, all); 37 } 38 return all; 39 } 40 public static void main(String[] args){ 41 int[] input={-1,5,-4,8,-4,9,10,-6,1,-9}; 42 System.out.println(GetMaxSum(input, 0, input.length-1)); 43 System.out.println(GetMaxSum2(input)); 44 } 45 }
浙公网安备 33010602011771号