標籤:style blog color ar for 資料 2014 div sp
從今天開始每天爭取自己手寫一兩個小程式,即使是從書上看的,或者從網上學的,都自己手動地把代碼打出來,貼在這裡。
培養自己這個習慣,盡最大可能堅持下來。
水滴石穿,繩鋸木斷。
2014年9月10日
今天學習的是:求最大子序列和
有三種演算法:
1 複雜度為O(N2)
1 package findmaxsub; 2 3 //求最大子序列和演算法1:相當是遍曆了一遍 4 5 public class FindMaxSu { 6 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 int[] a = new int[] {4,-3,5,-2,-1,2,6,-2,10};10 System.out.println(findMax(a));11 12 }13 private static int findMax(int [] array){14 int maxSum = 0;15 for(int i=0;i<array.length;i++){16 int sum=0;17 for(int j=i;j<array.length;j++){18 sum+=array[j];19 if(sum>maxSum){//注意這個if的位置20 maxSum=sum;21 }22 } 23 }24 return maxSum;25 }26 }
2 複雜度為O(NlogN)
1 package findmaxsub; 2 3 //尋找最大子序列和的演算法2 4 //基本思路:最大子序列和三種情況:出現在資料的左半部分,右半部分,跨越資料的中部從而位於左右兩半部分之中 5 //前兩種情況用遞迴,後一種情況簡單地用兩個for迴圈就行了 6 7 //分而治之的思想:divide-and-conquer 8 //遞迴的思想 9 //關鍵是處理第三種情況為什麼能用兩個簡單的迴圈:因為子序列的頭已經確定了,必須包含這個中間的元素10 11 public class FindMaxSub {12 13 /**14 * @param args15 */16 public static void main(String[] args) {17 // TODO Auto-generated method stub18 19 int[] arr = new int[]{4,-3,5,-2,-1,2,6,-2,10};20 System.out.println(maxSub(arr,0,arr.length-1));21 22 23 }24 25 private static int maxSub(int [] array,int left,int right){26 if(left==right){27 if (array[left]>0)28 return array[left];29 else30 return 0;31 }32 int center= (left+right)/2;33 //前兩種情況用遞迴34 int leftMax=maxSub(array,left,center);35 int rightMax=maxSub(array,center+1,right);36 37 //後一種情況用兩個for迴圈38 int leftBorderMax=0; int leftBorderSum=0;39 for(int i=center;i>=left;i--){40 leftBorderSum+=array[i];41 if(leftBorderSum>leftBorderMax){42 leftBorderMax=leftBorderSum;43 }44 }45 int rightBorderMax=0; int rightBorderSum=0;46 for(int i=center+1;i<=right;i++){47 rightBorderSum+=array[i];48 if(rightBorderSum>rightBorderMax){49 rightBorderMax=rightBorderSum;50 }51 }52 53 return max3(leftMax,rightMax,leftBorderMax+rightBorderMax);54 55 }56 57 private static int max3(int a, int b, int c){58 int n=a>b?a:b;59 return c>n?c:n;60 }61 62 }
3 複雜度為O(N)
1 package findmaxsub; 2 //求最大子序列和演算法3: 3 //這個演算法最巧妙,時間運行最小 4 //基於的思想:任何最大子序列的起點項不可能為負數,那麼任何負的子序列不可能是最大子序列的首碼 5 //所以只要前面的累積和為負數了,就可以重新選擇開頭了 6 7 public class findMaxSubb { 8 9 /**10 * @param args11 */12 public static void main(String[] args) {13 // TODO Auto-generated method stub14 int [] arr = new int[]{4,-3,5,-2,-1,2,6,-2};15 System.out.println(findMax(arr));16 17 }18 private static int findMax(int[] arr){19 int sum=0,maxSum=0;20 for(int i=0;i<arr.length;i++){21 sum+=arr[i];22 if(sum<0)23 sum=0;24 if(sum>maxSum){25 maxSum=sum;26 }27 }28 return maxSum;29 }30 31 }
每日一記,今天開始