动态规划—最大子数组和

168 阅读2分钟

「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战

Hope is a good thing, maybe the best of things. And no good thing ever dies—— 《The Shawshank Redemption》

前言

动态规划的算法系列是面试中经常见到的算法类型题,上一篇文章我们大致介绍了一下什么是动态规划、动态规划的特点:动态规划—斐波那契数

今天继续来学习一道关于动态规划的算法题来加强算法能力。

题目

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

子数组是数组中的一个连续部分。

示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:
输入:nums = [1]
输出:1

示例 3:
输入:nums = [5,4,-1,7,8]
输出:23

思路分析

  • 动态规划的是首先对数组进行遍历,当前最大连续子序列和为 sum,结果为 ans
  • 如果 sum > 0,则说明 sum 对结果有增益效果,则 sum 保留并加上当前遍历数字
  • 如果 sum <= 0,则说明 sum 对结果无增益效果,需要舍弃,则 sum 直接更新为当前遍历数字
  • 每次比较 sumans的大小,将最大值置为ans,遍历结束返回结果

算法实现

  • 使用 for 循环,判断每个值的大小
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    // 从数组的第一个元素开始
    let ans = nums[0];
    // 数组元素的和
    let sum = 0;
    // 遍历一遍数组
    for(const num of nums) {
        对大于0的元素进行累加
        if(sum > 0) {
            sum += num;
        } else {
        // 如果小于0,数组将不再有连续性
            sum = num;
        }
        // 返回大的值
        ans = Math.max(ans, sum);
    }
    return ans;
};

  • 使用 forEach 和 Math.max 获取累计后更大的值
var maxSubArray = function(nums) {
    let sum = 0, maxAns = nums[0];
    // 遍历数组
    nums.forEach((x) => {
        // 累加后获取相对更大的值
        sum = Math.max(sum + x, x);
        maxAns = Math.max(maxAns, sum);
    });
    return maxAns;
};

image.png

复杂度分析

  • 时间复杂度:O(n),其中 nnums 数组的长度。我们只需要遍历一遍数组即可求得答案
  • 空间复杂度:O(1),我们只需要常数空间存放若干变量。

结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。

文章如有错误之处,希望在评论区指正🙏🙏

欢迎关注我的微信公众号,一起交流技术,微信搜索 🔍 :「 五十年以后