求解最大子序列和

来源:互联网 发布:雪梨家淘宝店铺 编辑:程序博客网 时间:2024/04/30 02:00
从一串数据中算出最大的子序列和,这里提供了三种方法,方案一到方案三中算法由劣到优。
例如:-2,11,-4,13,-5,-2,答案为20(从A2到A4)



方案一:
public static int maxSubSum(int a []){
   int maxSum=0;
   for(int i=0; i<a.length; i++)
       for(int j=i; j<a.length; j++){
             int thisSum=0;
             for(int k=i; k<=j; k++)
                  thisSum+=a[k];
             if(thisSum>maxSum)
                  maxSum=thisSum;
          }
   return maxSum;
}
此种方案的时间复杂度大概为N的三次方,可以这样来分析:三次for循环,每次循环为N,所以三次迭代的循环大概为N的三次方。



方案二:
public static int maxSubSum(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;
}
此种方案的时间复杂度为N的平方,理解与第一种相同,这种方法相对于第一种方案较好。



方案三:
public static int maxSubSum(int a []){
   int maxSum=0;
   int thisSum=0;
   for(int i=0; i<a.length; i++){
         thisSum+=a[i];
         if(thisSum>maxSum)
            maxSum=thisSum;
         else if(thisSum<0)
            thisSum=0;
       }
   return maxSum;
}
此种方案的时间复杂度为N,在三种方案中最优。运行时间是明显的,但是不容易看出正确性。我们可以分析出这样的结论,如果a[i]是负的,那么它不可能代表最优序列的起点,因为任何包含a[i]的作为起点的子序列都可以通过用a[i+1]作为起点而改进。类似地,任何负的子序列不可能是最优子序列的前缀(原理相同)。


小结:其实除此三种算法,还有一种时间复杂度为N*logN的递归算法。方法稍微有点复杂,如果读者感兴趣可以借鉴其他文章。












原创粉丝点击