zoukankan      html  css  js  c++  java
  • 使用分治法求最大子序列之和

    对于求最大子序列之和,对于我这样的菜鸟,首先想到的应该是最暴力的方法,就是将所有的子序列的和进行比较,然后出现最大值并返回答案。不过这也没啥意思,复杂度O(N2).

    对这个问题,有一个相对复杂的O(NlogN)的解法,就是使用递归。其主要思想是:比较左、右、中间三部分的序列和的大小,因为中间部分是没办法分治的,只能在每一层递归函数空间里面进行,所以递归的部分为左、右,而且左右部分序列和有分别为次层递归的结果。递归的基本边界:左右为相同位置元素,即只有一个元素.

     1 private static int maxSumRec(int [] a , int left , int right){
     2   if( left == right ){//边界①
     3     if( a[left] > 0 )
     4       return a[left];
     5     else
     6       return 0;
     7   }
     8   //递归分治部分②
     9   int center = (left + right) / 2;
    10   int maxLeftSum = maxSumRec( a, left, center);
    11   int maxRightSum = maxSumRec( a, center + 1, right);
    12 
    13   //对改层的部分进行数据处理③
    14   int maxLeftBorderSum = 0, leftBorderSum = 0;
    15   for( int i = center; i >= left; i--){
    16     leftBorder += a[i];
    17     if( maxLeftBorderSum < leftBorderSum)
    18       maxLeftBorderSum = leftBorderSum;
    19   }
    20   
    21   int maxRightBorderSum = 0, leftBorderSum = 0;
    22   for( int i = center + 1; i <= right; i ++){
    23     rightBorderSum += a[i];
    24     if( maxRightBorderSum > rightBorderSum)
    25       maxRightBorderSum = rightBorderSum;
    26   }
    27 
    28   //返回
    29   return max3( maxRightBorderSum + maxLeftBorderSum , maxLeftSum , maxRightSum);
    30 }

    复杂度:

    如果数据量为N,①与数据两无关,时间为常数;③为数据处理部分,时间为O(N);②为递归部分,每一层的该处时间消耗总与上一层有关,并有T(N)=T(N/2)+O(N)的关系.

    最后计算得T(N)=O(NlogN).

    下面是一个时间复杂度更小(O(N))的算法:

    该算法更为简便之处是忽略了对子序列的寻找比较,而是根据规律直接找出最佳答案.

    对于含有正数的序列而言,最大子序列肯定是正数,所以头尾肯定都是正数.我们可以从第一个正数开始算起,每往后加一个数便更新一次和的最大值;当当前和成为负数时,则表明此前序列无法为后面提供最大子序列和,因此必须重新确定序列首项.

     1 public class maxSubSumS {
     2     public static int maxSubSum(int [] a ){
     3         int maxSum = 0 , thisSum = 0;
     4         for( int i = 0; i < a.length ; i ++ ){
     5             thisSum += a[ i ];
     6             if(thisSum > maxSum)
     7                 maxSum = thisSum;
     8             else if(thisSum < 0)
     9                 thisSum = 0;
    10         }
    11         return maxSum;
    12     }
    13 }
  • 相关阅读:
    MySQL for Linux错误: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    Git SSH Key 生成步骤
    百度陆奇最新内部演讲:如何成为一个优秀的工程师?
    Apple使用Apache Mesos重建Siri后端服务
    剖析Elasticsearch集群系列第一篇 Elasticsearch的存储模型和读写操作
    ElasticSearch VS Solr
    聊聊基于Lucene的搜索引擎核心技术实践
    如何安全的存储用户密码?
    MySQL 性能管理及架构设计指南
    大牛是怎么思考设计MySQL优化方案
  • 原文地址:https://www.cnblogs.com/sunnysola/p/4795691.html
Copyright © 2011-2022 走看看