LeetCode之HOT100--053 最大子数组和

131 阅读1分钟

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

前言

一直都计划学习数据结构与基本算法,但是平时都看一阵停一阵。现在决心坚持下去,我准备从LeetCode的HOT100开始,每天完成1~2道习题,本系列的题解都将使用swift语言完成。本文更新的是LeetCode中HOT100的第24题053 最大子数组和。

题目

给你一个整数数组 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

提示:

1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4

分析

本题要求的是最大连续子序列的和,那么对于数组中的任一元素i而言,我们记第i个元素的最大连续子序列的和为sum(i),那么sum(i)有两种情况:

  • 第一就是前(i-1)元素的最大连续子序列和加上当前元素,即sum(i-1)+ num[i],
  • 第二种就是不考虑sum(i-1), 直接取当前元素,即num[i]。
  • sum(i)就应该等于这两种情况的较大值。 所以,如果前(i-1)元素的最大连续子序列和sum(i-1)<= 0时,两者的较大值就是num[i],反之则是sum(i-1)+ num[i]。所以这道题用动态规划的思路并不难解决,动态规划方法的思路如下:
1、创建变量分别保存信息为当前最大连续子序列和为 curMaxSum,结果为 maxSum
2、对数组进行遍历
    * 如果 curMaxSum > 0,则说明 curMaxSum 对结果有增益效果,则 maxSum 保留并加上当前遍历数字
    * 如果 curMaxSum <= 0,则说明 curMaxSum 对结果无增益效果,需要舍弃,则 maxSum 直接更新为当前遍历数字
    * 每次比较 sum 和 ans的大小,将最大值置为ans,遍历结束返回结果
3、返回结果值 maxSum

题解

class KLLC053 {
    func maxSubArray(_ nums: [Int]) -> Int {
        if nums.count <= 0 {
            return 0
        }
        var curMaxSum = nums[0] //当前连续最大总和
        var maxSum = curMaxSum //历史连续最大总和
        for i in (1..<nums.count) {
            //i-1的连续最大总和小于0,则当前i的连续最大总和就是元素i的值
            //i-1的连续最大总和大于等于0,则当前i的连续最大总和就是元素i的值 + i-1的连续最大总和
            if curMaxSum < 0 {
                curMaxSum = nums[i]
            } else {
                curMaxSum += nums[i]
            }
            //更新 历史连续最大总和 maxSum
            maxSum = maxSum > curMaxSum ? maxSum : curMaxSum
        }
        //返回结果
        return maxSum
    }
}