算法设计与分析第二章作业

软工2101欧阳腾 2022-09-24 01:14:27

最大子段和分治算法描述及伪代码

用分治法求最大字段和的三种计算情况:
首先在数组 mid = (right - left) / 2 出将数组分开

  1. 可能出现在左子数组
  2. 可能出现在有子数组
  3. 可能在包含mid的左右两边
    所以我们考虑递归计算左段最大子段和 FindLeft 、递归计算右段最大子段和 FindRight 、递归计算mid到最左边的最大和S1和到最右边的最大和S2,即S1+S2
    最后,max{FindLeft, FindRight, S1+S2}即可得到答案

伪代码如下:

//伪代码
Function<MaxSum> (int* a, int left , int right){
    //传值:数组a,左右边界
     if right-left=1 then
        return
    end if
    
    // 划分[left,mid)和[mid,right)分治
    mid←x+(y-x)/2
    L←maxsum(a,left,mid)
    R←maxsum(a,mid+1,right)
    if L>R then
        max←L
    else
        max←R
    end if
    // 求出处于中间的连续子序列最大和
    // 先求从中间向左最大值
    tempSum←0
    leftSum←a[m-1]
    for i←m-1 downto right do
        tempSum←tempSum+a[i]
        if leftSum<tempSum then
            leftSum←tempSum
        end if
    end for
    // 再求从中间向右最大值
    tempSum←0
    rightSum←a[m]
    for i←m to left do
        tempSum←tempSum+a[i]
        if rightSum<tempSum then
            rightSum←tempSum
        end if
    end for
    midSum←leftSum+rightSum
    if max<midSum then
        max←midSum
    end if
    return max
end Function
}

程序代码:

int MaxSum(int *a, int left, int right)
 {
    if(right==left)
      return a[left]>0?a[left]:0;
 
    int mid = (left+right)/2;
    //左边区间的最大子段和
    int leftMax = MaxSum (a,left,mid);
    //右边区间的最大子段和
    int rightMax = MaxSum(a,mid+1,right);
 
    //以下求端点分别位于不同部分的最大子段和
 
    //center开始向左移动
    int sum = 0;
    int left_max = 0;
    for(int i = mid; i >= left; --i)
    {
       sum += a[i];
       if(sum > left_max)
          left_max = sum;
    }
    //center+1开始向右移动
    sum = 0;
    int right_max = 0;
    for(int i = mid+1; i <= right; ++i)
    {
       sum += a[i];
       if(sum > right_max)
         right_max = sum;
    }
    int res = left_max+right_max;
    if(res < leftMaxInterval)
        res = leftMaxInterval;
    if(res < rightMaxInterval)
        res = rightMaxInterval;
    return res;
 }

该算法的时间复杂度

分治法时间复杂度主要是将问题一分为二,分解成规模n/2的子问题,最后再合并子问题
T(c) = O(1)
T(n) = 2T(n/2) + O(n)
即 根据主定理有 T(n) = O(nlogn)

体会与思考

分治法可以将一个难以直接解决的大问题,划分成一些规模较小的子问题,以便各个击破,分而治之,如此分解下去,直到问题规模足够小,很容易求出其解为止,再将子问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解。代码结构也会十分清晰,比较简洁明了。

...全文
70 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

434

社区成员

发帖
与我相关
我的任务
社区描述
广东外语外贸大学信息科学与技术学院
算法 高校
社区管理员
  • brisksea
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧