【算法(四·二):动态规划思想——最大子数组问题Ⅱ】

算法介绍

最大子数组问题是一个经典的问题,可以有效地使用动态规划思想来解决。利用动态规划思想来解决此问题比利用传统的蛮力枚举算法与优化枚举算法以及之前介绍的分治思想算法取得了更低的时间复杂度。这个问题的目标是在一个整数数组中找到一个连续的子数组,使得子数组的元素之和最大。
在这里插入图片描述

问题分析

给出问题

有如下数组,求其最大子数组。
在这里插入图片描述

枚举过程分析

  • 参数说明
    • 当前最大值:𝒊,𝒋枚举过程中,子数组和的最大值。
    • S(𝒊,𝒋):𝒊,𝒋枚举过程中,子数组和。
    • 𝑫𝒊:以𝑿[𝒊]开头的最大子数组。
  • 枚举过程
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 观察𝑫𝒊

在这里插入图片描述在这里插入图片描述

  • 结尾相同D1,D2,D3
    在这里插入图片描述

  • 结尾不同D3,D4
    在这里插入图片描述

  • 规律描述

    • 情况1
      在这里插入图片描述

    • 情况1 验证成功
      在这里插入图片描述

    • 情况2
      在这里插入图片描述

    • 情况2 验证成功
      在这里插入图片描述

算法步骤

基于上述规律,我们可以将此问题结合动态规划思想来解决。

  • 问题结构分析
    • 明确原始问题
      在这里插入图片描述

    • 给出问题表示
      在这里插入图片描述

  • 递推关系建立
    • 分析最优(子)结构
      D[i]依赖于D[i+1]
      在这里插入图片描述
    • 构造递推公式
      在这里插入图片描述
  • 自底向上计算
    • 确定计算顺序
      • 状态初始化
        𝑫[𝒏] = 𝑿[𝒏] (注:𝑫[𝒏]就是𝑿[𝒏])在这里插入图片描述
      • 明确子问题依赖关系
        根据递推公式可知,D[i]依赖于 X[i] 与D [i+1]
        在这里插入图片描述
    • 依次求解问题
      故计算顺序是“从右往左”这样的自底向上计算。
      在这里插入图片描述
  • 最优方案追踪
    • 构造追踪数组𝑹𝒆𝒄[𝟏. . 𝒏]
      用以存放最大子数组的结尾位置,如𝑹𝒆c[𝒊]存放的是D[i]的结尾位置。
      • 情况1:结尾相同,故 𝑹𝒆𝒄[𝒊] = 𝑹𝒆𝒄[𝒊 + 𝟏]
        原因:𝑫[𝒊 + 𝟏]>0,𝑫[𝒊 ]与 𝑫[𝒊 + 𝟏]结尾的位置相同。因此𝑹𝒆𝒄[𝒊] 与𝑹𝒆𝒄[𝒊 + 𝟏]存放的都是这个结尾位置的坐标。在这里插入图片描述
        • 情况2:结尾不同,𝑹𝒆𝒄[𝒊] = 𝒊
          原因:𝑫[𝒊 + 𝟏]<=0,𝑫[𝒊]的结尾位置就是X[i]处,𝑫[𝒊]存放的就是X[i]的坐标。
          在这里插入图片描述
    • 找到最优解
      从D中找到最大子数组和的最优解,i是最大子数组开头位置,Rec[i]里存放的是最大子数组结尾位置。
      在这里插入图片描述

算法实例

  • 实例问题
    给定如下数组,求最大子数组。
    在这里插入图片描述

  • 实例算法过程
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

  • 最终结果
    在这里插入图片描述

算法伪代码

输入:数组X,数组长度n
输出:最大子数组和Smax,子数组起止位置l,r
新建一维数组D[1...n]和Rec[1...n]
//初始化
D[n] = X[n]
Rec[n] = n
//动态规划
for i = n-1 to 1 do
    if D[i+1] > 0 then
        D[i] = X[i] + D[i+1]
        Rec[i] = Rec[i+1]
    end 
    else
        D[i] = X[i] 
        Rec[i] = i
    end
end
//查找解
Smax = D[1]
for i = 2 to n do 
    if Smax < D[i] then
        Smax = D[i]
        l = i
        r = Rec[i]
    end 
end
return Smax,l,r         

算法性能

时间复杂度

计算最大子数组的算法具有线性时间复杂度,即O(n),其中n是数组的长度。算法遍历数组一次,对每个元素执行一些基本的比较和加法操作。因此,算法的时间复杂度与数组的大小成线性关系,具有高效性能。

空间复杂度

算法的空间复杂度是O(1),即常数级别的额外空间。除了几个用于存储最大子数组和索引的变量外,算法没有使用额外的空间。

稳定性

动态规划解决最大子数组问题的算法是稳定的。这意味着对于相同的输入数据或相同的数组,算法总是产生相同的输出结果。

算法总结

总的来说,利用动态规划思想解决最大子数组问题在性能上非常出色,尤其适用于处理大规模的数组,并且其线性时间复杂度O(n)比利用分治思想解决此问题的线性对数时间复杂度O(nlogn)要低的多。算法的空间复杂度也非常低,只需要几个额外的变量,因此占用的内存也很少。故日后遇到求取最大子数组问题时,应优先考虑动态规划思想。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值