动态规划求解最大子序列和

1 求解最大子序列和题目

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: nums = [2, 3, -6, 2, 4]
输出: 6
解释: 连续子数组 [2,4] 的和最大,为 6。

2 方法分析

本节来源:
https://leetcode-cn.com/problems/maximum-subarray/solution/xiang-xi-jie-du-dong-tai-gui-hua-de-shi-xian-yi-li/

解题思路:
示例: [a, b , c, d , e]

解答这类题目, 省略不掉遍历, 因此我们先从遍历方式说起

通常我们遍历子串或者子序列有三种遍历方式

  1. 以某个节点为开头的所有子序列: 如 [a],[a, b],[ a, b, c] … 再从以 b 为开头的子序列开始遍历 [b]
    [b, c]。
  2. 根据子序列的长度为标杆,如先遍历出子序列长度为 1 的子序列,在遍历出长度为 2 的 等等。
  3. 以子序列的结束节点为基准,先遍历出以某个节点为结束的所有子序列,因为每个节点都可能会是子序列的结束节点,因此要遍历下整个序列,如: 以
    b 为结束点的所有子序列: [a , b] [b] 以 c 为结束点的所有子序列: [a, b, c] [b, c] [ c ]。

第一种遍历方式通常用于暴力解法, 第二种遍历方式用于解最长回文子串。
第三种遍历方式 因为可以产生递推关系, 采用动态规划时, 经常通过此种遍历方式, 如 背包问题, 最大公共子串 , 这里的动态规划解法也是以 先遍历出 以某个节点为结束节点的所有子序列 的思路

对于刚接触动态规划的, 我感觉熟悉第三种遍历方式是需要抓住的核心

因为我们通常的惯性思维是以子序列的开头为基准,先遍历出以 a 为开头的所有子序列,再遍历出以 b 为开头的…但是动态规划为了找到不同子序列之间的递推关系,恰恰是以子序列的结束点为基准的,这点开阔了我们的思路。

3 动态规划法

关于动态规划法,前面的文章有介绍:动态规划
动态规划的核心算法为:
若前一个元素大于0,则将其加到当前元素上
如这个例子,如下图所示,当i为0时,当前元素为本身2;当i为1时,因为前一元素2大于0,因此,当前元素变为当前值加前一个元素,为5;当i为2时,因为前一元素5大于0,因此,当前元素变为当前值加前一个元素,为-1;当i为3时,因为前一元素-1小于0,因此,当前元素不变,为2;当i为4时,因为前一元素2大于0,因此,当前元素变为当前值加前一个元素,为6。
最大子序列和为dp数组的最大值。
动态规划求解最大子序列和_第1张图片

4 代码实现

python代码实现如下:

nums = [2, 3, -6, 2, 4]

def maxSubArray():
    for i in range(1, len(nums)):
        if nums[i - 1] > 0:
            nums[i] += nums[i - 1]
    return max(nums)

print(maxSubArray())

值得注意的是,当运行结束以后,源数组nums的值已经发生了变化。

你可能感兴趣的:(数据结构)