「这是我参与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
}
}