• 最大子序列问题


    输入一组整数,求出这组数字子序列和中最大值。也就是只要求出最大子序列的和,不必求出最大的那个序列。例如:

    序列:-2 11 -4 13 -5 -2,则最大子序列和为20

    序列:-6 2 4 -7 5 3 2 -1 6 -9 10 -2,则最大子序列和为16

        

    1.对这个问题,有一个相对复杂的O(NlogN)的解法,就是使用递归。该方法我们采用分治策略divide-and-conquer)。

    在我们例子中,最大子序列可能在三个地方出现,或者在左半部,或者在右半部,或者跨越输入数据的中部而占据左右两部分。前两种情况递归求解,第三种情况的最大和可以通过求出前半部分最大和(包含前半部分最后一个元素)以及后半部分最大和(包含后半部分的第一个元素)相加而得到。

    //递归法,复杂度是O(nlogn) 
    long maxSumRec(const vector<int>& a, int left, int right) 
    { 
           if (left == right) 
           { 
                  if (a[left] > 0) 
                         return a[left]; 
                  else 
                         return 0; 
           } 
           int center = (left + right) / 2; 
           long maxLeftSum = maxSumRec(a, left, center); 
           long maxRightSum = maxSumRec(a, center+1, right); 
     
           //求出以左边对后一个数字结尾的序列最大值 
           long maxLeftBorderSum = 0, leftBorderSum = 0; 
           for (int i = center; i >= left; i--) 
           { 
                  leftBorderSum += a[i]; 
                  if (leftBorderSum > maxLeftBorderSum) 
                         maxLeftBorderSum = leftBorderSum; 
           } 
     
           //求出以右边对后一个数字结尾的序列最大值 
           long maxRightBorderSum = 0, rightBorderSum = 0; 
           for (int j = center+1; j <= right; j++) 
           { 
                  rightBorderSum += a[j]; 
                  if (rightBorderSum > maxRightBorderSum) 
                         maxRightBorderSum = rightBorderSum; 
           } 
     
           return max3(maxLeftSum, maxRightSum,  
                  maxLeftBorderSum + maxRightBorderSum); 
    } 
     
    long maxSubSum3(const vector<int>& a) 
    { 
           return maxSumRec(a, 0, a.size()-1); 
    }

    2.

    下面介绍一个线性的算法,这个算法是许多聪明算法的典型:运行时间是明显的,但是正确性则很不明显(不容易理解)。全部为负数的情况,特殊处理。

    //线性的算法O(N) 

    long maxSubSum4(const vector<int>& a) 
    
    { 
    
           long maxSum = 0, thisSum = 0; 
    
           for (int j = 0; j < a.size(); j++) 
    
           { 
    
                  thisSum += a[j]; 
    
                  if (thisSum > maxSum) 
    
                         maxSum = thisSum; 
    
                  else if (thisSum < 0) 
    
                         thisSum = 0; 
    
           } 
    
           return maxSum; 
    
    }
  • 相关阅读:
    GX转账站点无法访问的问题

    .NET易忘备留 ORACLE存储过程调用
    Oracle 字符串函数
    Oracle 数值函数
    AJAX.JSONP 跨域
    机器人部署的注意事项
    IE6、7绝对定位层被遮挡的原因(主要是父层决定的)
    Oracle 新手问答
    字符设备驱动范例
  • 原文地址:https://www.cnblogs.com/drawwindows/p/2969173.html
Copyright © 2020-2023  润新知