最大子序列和的4中Java算法实现


第一种算法运行时间为O(N^3),第二种算法运行时间为O(N^2),第三种算法运行时间为O(nlogn),第四种算法运行时间为线性N


[java]  view plain  copy
 print ?
  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         int[] a = {-211, -413, -5, -2};//最大子序列和为20  
  4.         int[] b = {-624, -7532, -16, -910, -2};//最大子序列和为16  
  5.         System.out.println(maxSubSum4(a));  
  6.         System.out.println(maxSubSum4(b));  
  7.     }  
  8.     //最大子序列求和算法一  
  9.     public static int maxSubSum1(int[] a){  
  10.           
  11.         int maxSum = 0;  
  12.           
  13.         //从第i个开始找最大子序列和  
  14.         for(int i = 0; i < a.length; i++) {  
  15.               
  16.             //找第i到j的最大子序列和  
  17.             for(int j = i; j<a.length; j++) {  
  18.                   
  19.                 int thisSum = 0;  
  20.                   
  21.                 //计算从第i个开始,到第j个的和thisSum  
  22.                 for(int k = i; k<=j; k++){  
  23.                     thisSum += a[k];  
  24.                 }  
  25.                 //如果第i到第j个的和小于thisSum,则将thisSum赋值给maxSum  
  26.                 if(thisSum>maxSum) {  
  27.                     maxSum = thisSum;  
  28.                 }  
  29.             }  
  30.         }  
  31.         return maxSum;  
  32.     }  
  33.       
  34.     public static int maxSubSum2(int[] a) {  
  35.         int maxSum = 0;  
  36.         for(int i = 0; i < a.length; i++) {  
  37.             //将sumMax放在for循环外面,避免j的变化引起i到j的和sumMax要用for循环重新计算  
  38.             int sumMax = 0;  
  39.             for(int j = i; j < a.length; j++) {  
  40.                 sumMax += a[j];  
  41.                 if(sumMax>maxSum) {  
  42.                     maxSum = sumMax;  
  43.                 }  
  44.             }  
  45.         }  
  46.         return maxSum;  
  47.     }  
  48.       
  49.     //递归,分治策略  
  50.     //2分logn,for循环n,固O(nlogn)  
  51.     public static int maxSubSum3(int[] a) {  
  52.         return maxSumRec(a, 0, a.length - 1);  
  53.     }  
  54.     public static int maxSumRec(int[] a, int left, int right) {  
  55.         //递归中的基本情况  
  56.         if(left == right) {  
  57.             if(a[left] > 0return a[left];  
  58.             else return 0;  
  59.         }   
  60.         int center = (left + right) / 2;  
  61.         //最大子序列在左侧  
  62.         int maxLeftSum = maxSumRec(a, left, center);  
  63.         //最大子序列在右侧  
  64.         int maxRightSum = maxSumRec(a, center+1, right);  
  65.         //最大子序列在中间(左边靠近中间的最大子序列+右边靠近中间的最大子序列)  
  66.         int maxLeftBorderSum = 0, leftBorderSum = 0;  
  67.         for(int i = center; i>=left; i--) {  
  68.             leftBorderSum += a[i];  
  69.             if(leftBorderSum > maxLeftBorderSum) maxLeftBorderSum = leftBorderSum;  
  70.         }  
  71.         int maxRightBorderSum = 0, rightBorderSum = 0;  
  72.         for(int i = center+1; i<= right; i++) {  
  73.             rightBorderSum += a[i];  
  74.             if(rightBorderSum > maxRightBorderSum) maxRightBorderSum = rightBorderSum;  
  75.         }  
  76.         //返回最大子序列在左侧,在右侧,在中间求出的值中的最大的  
  77.         return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);  
  78.     }  
  79.     public static int max3(int a, int b, int c) {  
  80.         return a > b?(a>c?a:c):(b>c?b:c);  
  81.     }  
  82.     //任何a[i]为负时,均不可能作为最大子序列前缀;任何负的子序列不可能是最有子序列的前缀  
  83.     public static int maxSubSum4 (int [] a) {  
  84.         int maxSum = 0, thisSum = 0;  
  85.         for(int j = 0; j < a.length; j++) {  
  86.             thisSum += a[j];  
  87.             if(thisSum>maxSum) maxSum = thisSum;  
  88.             else if (thisSum < 0) thisSum = 0;   
  89.         }  
  90.         return maxSum;  
  91.     }  
  92. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值