笔记-最大子序列

来源:互联网 发布:php开源b2c商城 编辑:程序博客网 时间:2024/06/05 15:17

   算法一:

<div>{CSDN:CODE:maxsubsum1.java}</div>


三次循环  O(N³)


   算法二:

public static int maxSubSum(int []a){int maxSum = 0;for(int i=0;i<a.length;){int thisSum = 0;for(int j=i;j<a.length;j++){thisSum+=a[j];if(thisSum>maxSum){maxSum = thisSum;}}}return maxSum;}

每次计算i到j的和
两次循环  O(N²)

   算法三:

public static int  maxSubSum(int []a){int maxSum = 0,thisSum=0;for(int i;i<a.length;i++){thisSum+=a[i];if(thisSum>maxSum){maxSum = thisSum;}else if(thisSum<0){thisSum = 0;}}return maxSum;}

算法二的优化。对任意thisSum,若thisSum<0,就舍弃(即令thisSum=0)。否则继续加值必然变小。
一次循环 O(N)

   算法四:分治

public static int  maxSubSum(int []a){return execute(a,0,a.length);}public int execute(int []a,int left,int right){if(left==right){        //Base Caseif(a[left]>0)return a[left];else return 0;}int center = (left+right)/2;int leftMaxSum = execute(int []a,int left,int center);int rightMaxSum = execute(int []a,int center+1,right);int maxLeftBorderSum = 0,thisLeftBorderSum = 0;for(int i=center;i>=0;i--){thisLeftBorderSum+=a[i];if(thisLeftBorderSum>maxLeftBorderSum)maxLeftBorderSum = thisLeftBorderSum;}int maxRightBorderSum = 0,thisRightBorderSum = 0;for(int i=center+1;i<=a.length;i++){thisRightBorderSum+=a[i];if(thisRightBorderSum>maxRightBorderSum)maxRightBorderSum = thisRightBorderSum;}return max3(leftMaxSum ,rightMaxSum ,maxLeftBorderSum+maxRightBorderSum);}

最大子序列应该在左边,右边,过中点的两边各有。这三种情况之中。
每次求左边(右边)的最大子序列,又可以将其看作新的母序列。所以可用递归。

1 0
原创粉丝点击