算法 | 最大子序列(数组)和

96 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情

最大子序列和问题也是数据结构中出现频率很高的一个问题,这个问题的核心是利用动态规划的思维来解决问题。可以使用动态规划解决的问题,可能是类似于本题的最大值求解,或是图、树结构中最短路径/最短时间/最优位置等求解。

在数据结构中,背包问题是使用动态规划的一道经典题目,下面这道题目也是利用动态规划来解决:

提供一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]

输出:6

解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

leetcode 对应题目: 53. 最大子数组和

解决方案:

    1. 动态规划
    1. 分治法

动态规划: 找到动态转移方程,就是实现本题目的核心。定义一个 f() 函数,其中 f(x) 表示第 x 个数结尾的连续子数组的和的最大值。

其中,Math.max(a,b)用来求 a、b 之间的最大值。

代码实现:

const maxSubArray = function(nums) {
    let pre = 0, maxAns = nums[0];
    nums.forEach((x) => {
        pre = Math.max(pre + x, x);
        maxAns = Math.max(maxAns, pre);
    });
    return maxAns;
};

这段代码的复杂度:

  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

注:动态规划在数据结构中经常会和一种叫做贪心的算法进行对比记忆,也是比较容易混淆的部分。在每一步都会有过程及决策,动态规划更关心过程,并且后面元素的状态取决于前面元素的状态;

而贪心算法相反,它并不关心过程,每一次决策都选择最好的结果,通过子结构的最优来得到整体的最优(不一定是整体的最优,但无限趋近于最优)