JAVA 求最大子序列和 算法

起因:给定一个整数序列,可能包含正数或负数。设计一个算法寻找它的一个子序列,其数字的和最大。
方案一(最耗时) 、
/**
 * 全部结果都进行比较
 * eg: 序列集合是 {1,2,3}
 *       i      j       thisSum       maxSum
 *       0      0          1            1
 *              1          3            3
 *              2          6            6
 *       1      1          2            6
 *              2          5            6
 *       2      2          3            6
 *
 * 最终把maxSum 返回就是最大子序列和 
 * */
public static int maxSubSum1(int[] a) {
    int maxSum = 0;
    for (int i = 0; i < a.length; i++) {
        int thisSum = 0;
        for (int j = i; j < a.length; j++) {
            thisSum += a[j];
            if (thisSum > maxSum) {
                maxSum = thisSum;
            }
        }
    }
    return maxSum;
}
 
  
方案二、(折半递归 耗时较方案一更少) 
 
  
/**
  * 结果折半进行比较 递归 效率比第一种快速很多
  * eg: 序列集合是 {1,2,3}
  *
  *       递归                  1                       2                      3
  *       left                  0                       0                      2
  *       right                 2                       1                      2
  *       leftMaxSum        maxSubSumRec(a, 0,1)=>3  maxSubSumRec(a,0,0)=>1    -
  *       rightMaxSum       maxSubSumRec(a,2,2)=>3   maxSubSumRec(a,1,1)=>2    -
  *       maxLeftBorderSum       3                       1                     -
  *       maxRightMaxSum         3                       2                     -
  *       maxSum                 6                       3                     3
  *  最终把maxSum 返回就是最大子序列和
  * */
 public static int maxSubSumRec(int[] a, int left, int right) {
     if (left == right) {
         return a[left];
     }
     int center = (left + right) / 2;
     int leftMaxSum = maxSubSumRec(a, left, center);
     int rightMaxSum = maxSubSumRec(a, center + 1, right);
     int leftBorderSum = 0, maxLeftBorderSum = 0;
     for (int i = center; i >= left; i--) {
         leftBorderSum += a[i];
         if (leftBorderSum > maxLeftBorderSum) {
             maxLeftBorderSum = leftBorderSum;
         }
     }
     int rightBorderSum = 0, maxRightBorderSum = 0;
     for (int i = center + 1; i <= right; i++) {
         rightBorderSum += a[i];
         if (rightBorderSum > maxRightBorderSum) {
             maxRightBorderSum = rightBorderSum;
         }
     }
     return max2(leftMaxSum, rightMaxSum, maxLeftBorderSum + maxRightBorderSum);
 }
// 获取最大值
public static int max2(int a, int b, int c) {
     int max = a;
     if (max < b) {
         max = b;
     }
     if (max < c) {
         max = c;
     }
     return max;
}
 
  
public static int maxSubSum2(int[] a) {
    return maxSubSumRec(a, 0, a.length - 1);
}

方案三、(最佳方案 耗时较以上两个方案更少) 
/**
 *  eg: {1,-2,4,6,-7,9}
 *  i    thisSum        maxSum
 *  0      1               1
 *  1      0               1
 *  2      4               4
 *  3      10              10
 *  4      3               10
 *  5      12              12
 * */
public static int maxSubSum3(int[] a) {
    int maxSum =0 ,thisSum =0;
    for(int i=0;ilength;i++){
        thisSum+=a[i];
        if(thisSum>maxSum){
            maxSum=thisSum;
        }else if(thisSum<0){
            thisSum=0;
        }
    }
    return maxSum;
}


你可能感兴趣的:(java,算法)