求陣列的連續子陣列之和的最大值
阿新 • • 發佈:2019-01-29
同一個問題:http://blog.csdn.net/witsmakemen/article/details/17740933
一個有N個整數元素的一維陣列{A[0],A[1],....,A[N-1],A[N]},這個陣列有很多連續的子陣列,那麼連續子陣列之和的最大的一個的值是什麼?
先給出一個時間複雜度為O(N^2)的求解程式實現,思想很簡單,就是遍歷陣列中所有的子陣列,程式碼如下:
/** * 計算陣列的最大子序列 * @author win7 * */ public class MaxSubArraySum { public static int sumN2(int [] array){ int sum=0,maxSum=Integer.MIN_VALUE; int n=array.length; int count=0; for(int i=0;i<n;i++){ sum=0; for(int j=i;j<n;j++){ sum+=array[j]; if(sum>maxSum){ maxSum=sum; } count++; } } System.out.println("length="+n+"||count="+count); return maxSum; } public static void main(String [] args){ // System.out.println("MIN_VALUE="+Integer.MIN_VALUE); int [] array={-5,-2,-3,-5,-3,-2}; int sum=MaxSubArraySum.sumN2(array); System.out.println("最大子序列和="+sum); } }
因為子陣列求和滿足動態規劃的後無效特性,所以可以使用動態規劃的思想,從分治的演算法中得到提示:可以考慮陣列的第一個元素A[0],以及最大的一段陣列(A[i],...A[j])跟A[0]之間的關係,有一下幾種情況:
1.當0=i=j時,元素A[0]元素本身構成和最大的一段;
2.當0=i<j時,和最大的一段以A[0]開始;
3.當0<i時,元素A[0]跟和最大的一段沒有關係。
從上面的三種情況可以將一個大問題(N個元素的陣列)轉化為一個較小的問題(n-1個元素的陣列)。假設知道(A[1],...,A[N-1])中包含A[1]的和最大的一段的和為start[1]。那麼,根據上面分析的三種情況,不難看出(A[0],...,A[N-1])中問題的解all[0]是三種情況的最大值max{A[0],A[0]+start[1],all[1]}。通過問題分析,可以看到問題滿足無後效性,可以使用動態規劃的方法來解決。
程式程式碼實現如下:
/** * 在時間複雜度為O(N)內找出陣列中最大的子序列的累加和 * @param array * @return */ public static int sumN(int [] array){ int n=array.length; int all=array[n-1],start=array[n-1]; int count=0; for(int i=n-2;i>=0;i--){ if((start+array[i])>array[i]){ start=start+array[i]; }else{ start=array[i]; } if(all<start){ all=start; } count++; } System.out.println("陣列長度="+array.length+"||時間複雜度="+count); return all; }