数据结构和算法-子序列和最大值问题(分治策略)


问题描述:存在序列A[1...n],序列中元素的值域为整数。求解序列A中子序列A[p,...,q]的元素和为最大值子序列?

解决思路 : 设m为↓[(1+n)/2]向下取整的即中点,则A最大值子序列在是下面序列中最大值子序列中之一

A[1,...,m](中点左侧 包括中点)   

A[i,...,j] 其中1 <= i <= m < j <= n (横跨中点)  

A[m+1,n](中点右侧 不包括中点) 

这样将求A最大值子序列问题转移求A[1,...,m]、A[i,...,j] 其中1 <= i <= m < j <= n 、A[m+1,n]三者中最大值子序列的问题,获取三者种最大一个;

1 先来获取A[i,...,j] 其中1 <= i <= m < j <= n中最大子序列(横跨中点)

伪代码如下:

序列

FIX-MAX-CROSSING-SUBARRAY(A , low , mid , high) {

        // 先求A[low , mid]这端子序列最大值,因为要包括mid所以从mid开始

        left-sum = -∞;

        sum = 0;

        max-left;

        for (i = mid; i >= low; i++) {

           sum = sum + A[i];

           if(sum > letf-sum)  {

                left-sum = sum;

               max-left = i;

          }

       }

       // 再求A[mid+1, high]这端子序列最大值

       right-sum = -∞;

       sum = 0;

       max-right;

       for(i = mid+1; i <= high; i++) {

             sum = sum + A[i];       

            if(sum > right-sum)  {

                 right-sum = sum;

                 max-right = i;

          }

       }

       return (max-left , max-right , left-sum+right-sum);

}

这样就可以获取A[i,...,j] 其中1 <= i <= m < j <= n中最大子序列(横跨中点)

2 A[1,...,m](中点左侧 包括中点)   和  A[i,...,j] 其中1 <= i <= m < j <= n (横跨中点) ,俩个序列 像针对A序列一样进行分解,

直到分解成序列中元素只有1位,并且每次分解都需要调用 FIX-MAX-CROSSING-SUBARRAY(A , low , mid , high)  获取横跨中点序列的最大值;

伪代码如下 :

FIND-MAXIMUM-SUBARRAY(A , low , high) {

    if (low == high) {

        // 分解序列元素为1停止

        return (low , high , A[low])

   } else {

        // 每次分解序列工作

        mid = ↓[(low+high)/2];

       // 分解中点左右俩端序列

       (left-low , left-high , left-sum) = FIND-MAXIMUM-SUBARRAY(A , low , mid);

       (right-low , right-high , right-sum) = FIND-MAXIMUM-SUBARRAY(A , mid+1 , high);

       // 求出包含中点元素的序列的最大子序列

       (cross-low , cross-high , cross-sum) = FIX-MAX-CROSSING-SUBARRAY(A , low , mid , high)

       // 获取三个子序列中最大值最大那个

       if(left-sum >= right-sum and left-sum >= cross-sum) {

              return (left-low , left-high , left-sum)

       } else if(right-sum >= left-sum and right-sum >= cross-sum) {

             return (right-low , right-high , right-sum)

      } else {

            return (cross-low , cross-high , cross-sum)

     }

   }

}

 

通过递归调用可以求出序列A子序列和最大值问题

时间复杂度影响因素 : 序列项数

时间复杂度 : Θ(nlgn)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM