最大子段和最大子段积java实现

来源:互联网 发布:淘宝筛选 编辑:程序博客网 时间:2024/05/09 20:28
package edu.pku.ss.hlj;public class MaxSubSumRec   {  /** * 分治法求最大子段和 * @param a * @param left * @param right * @return */    private static int maxSumRec(int[] a, int left, int right)      {          if (left == right)          {              if (a[left] > 0)              {              System.out.print(a[left]+" ");                return a[left];            }              else              {                  return 0;              }          }            int center = (left + right) / 2;          int maxLeftSum = maxSumRec(a, left, center);          int maxRightSum = maxSumRec(a, center + 1, right);            int maxLeftBorderSum = 0;          int leftBorderSum = 0;          for (int i = center; i >= left; i--)          {              leftBorderSum += a[i];              if (leftBorderSum > maxLeftBorderSum)              {                  maxLeftBorderSum = leftBorderSum;              }          }            int maxRightBorderSum = 0;          int rightBorderSum = 0;          for (int i = center + 1; i <= right; i++)          {              rightBorderSum += a[i];              if (rightBorderSum > maxRightBorderSum)              {                  maxRightBorderSum = rightBorderSum;              }          }            return max(maxLeftSum, maxRightSum, maxRightBorderSum + maxLeftBorderSum);      }        //入口程序      public static int maxSubSum(int[] a)      {          return maxSumRec(a, 0, a.length - 1);      }        //求三数中的最大值      private static int max(int a, int b, int c)      {          int max = a > b ? a : b;          max = c > max ? c : max;            return max;      }    private static int max(int a,int b){    int max = a>b?a:b;    return max;    }    private static int min(int a,int b,int c){    int min = a<b?a:b;    min = min<c?min:c;    return min;    }    /**     * 动态规划方法一     * @param a     * @return     */    public static int maxSubSum2(int[] a)      {          int maxSum = 0;          int thisSum = 0;            for (int j = 0; j < a.length; j++)          {              thisSum += a[j];              if (thisSum > maxSum)              {                  maxSum = thisSum;              }              else if (thisSum < 0)              {                  thisSum = 0;              }          }            return maxSum;      }    /**     * 动态规划方法二     * @param a     * @return     */    public static int maxSubSum3(int[] a){    int maxSum = 0;    int thisSum = 0;//记录前一个最大是子段和C[i]=max{c[i-1]+a[i],a[i]}    for(int i=0;i<a.length;i++){    if(thisSum >0){    thisSum += a[i];    }else{    thisSum = a[i];    }    if(thisSum > maxSum){    System.out.print(a[i] + " ");    maxSum = thisSum;    }    }    return maxSum;    }    /**     * 动态规划方法三     * @param a     * @return     */    public static int maxS(int[] a){    int[] max = new int[25];    max[0] = a[0];    int maxSum = max[0];    for(int i=1;i<a.length;i++){    max[i] = max(max[i-1]+a[i],a[i]);    if(maxSum < max[i]){    maxSum = max[i];    }    }    return maxSum;    }        /**     * 最大子段积(动态规划)     * @param a     */    public static void multip(int[] a){    int[] min = new int[256];//记录到目前位置为止,最小的负数    int[] max = new int[256];//记录到目前位置为止,最大的正数    max[0] = a[0];//设置为第一个数值    min[0] = a[0];    int max_val = max[0];//记录最大乘积    for(int i=1;i<a.length;i++){    max[i] = max(max[i-1]*a[i],min[i-1]*a[i],a[i]);    min[i] = min(max[i-1]*a[i],min[i-1]*a[i],a[i]);//a[i]正负数都在这里了    if(max_val < max[i]){    max_val = max[i];    }    }    if(max_val < 0){    System.out.println(-1);    }else{    System.out.println(max_val);    }    }    public static void main(String[] args)       {          int[] a = {1,-2, 11, -4, 13, -5, -2};         int[] b = {1, -3,-2,-2, -3,0,8,5};//        System.out.println(MaxSubSumRec.maxSubSum(a));  //        System.out.println(maxSubSum3(a));        System.out.println(maxS(b));//        multip(b);    }  }  

0 0