携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情 。如果哪里写的不对,请大家评论批评。
最大子数组和
题目
给你一个整数数组 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<0,重置sum=0,重新开始找子数组
- 举例:[-2,1,-3,4,-1,2,1,-5,4]
- 定义一个
max_num来记录最终的结果,初始化的时候为极小数,一个cur_num来记录当前子数组的和 - 从左向右开始第一位
-2,cur_num = -2 + cur_num = -2,max_num = max(max_num,-2),所以max_num暂存-2(也是为了预防数组就一个-2的值) - 因为前一个
-2 < 0,所以放弃原来的值cur_num = 0,这时候值为1,cur_num = -1 + cur_num = 1,,max_num也是保存最大的值max_num = max(-2,1) = 1 - -3,
cur_num = -3 + cur_num = -2,,max_num也是保存最大的值max_num = max(-2,1) = 1,然后cur_num=-2 < 0, 所以cur_num = 0 - 4,
cur_num = 4 + cur_num = 4,,max_num也是保存最大的值max_num = max(4,1) = 4,然后cur_num=4 > 0, 所以cur_num = 4 - -1,
cur_num = -1 + cur_num = 3,,max_num也是保存最大的值max_num = max(3,4) = 4,然后cur_num=3 > 0, 所以cur_num = 3 - 2,
cur_num = 2 + cur_num = 5,,max_num也是保存最大的值max_num = max(5,4) = 5,然后cur_num=5 > 0, 所以cur_num = 5 - 1,
cur_num = 1 + cur_num = 6,,max_num也是保存最大的值max_num = max(6,5) = 6,然后cur_num=6 > 0, 所以cur_num = 6 - -5,
cur_num = -5 + cur_num = 1,,max_num也是保存最大的值max_num = max(1,6) = 6,然后cur_num=1 > 0, 所以cur_num = 1 - 4,
cur_num = 4 + cur_num = 5,,max_num也是保存最大的值max_num = max(5,6) = 6,然后cur_num=5 > 0, 所以cur_num = 5
代码
class Solution {
func maxSubArray(_ nums: [Int]) -> Int {
// 如果数组为nil,没有意义
guard nums.count > 0 else {
return 0
}
// 记录当前的和
var cur_num = 0
// 记录最大值,为了防止数组全是负数,初始化给出最小值
var max_num = Int.min
for value in nums {
// 当前累计的和
cur_num = cur_num+value
// 累计的和,保存的最大值,取最大
max_num = max(max_num, cur_num)
// 如果当前和小于0,没有相加的意义
if cur_num < 0 {
cur_num = 0
}
}
return max_num
}
}