法算day13

法算day13
lief
[up主专用,视频内嵌代码贴在这]
最大子数组和
问题描述
给你一个整数数组 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 <= 105
-104 <= nums[i] <= 104
问题分析
使用Kadane算法的核心思想是:遍历数组,计算以每个位置结束的最大子数组和
在每个位置,我们有两个选择:
将当前元素加入前面的子数组
以当前元素开始新的子数组
算法步骤示例(nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4])
- 初始状态
1
2currentSum = nums[0] = -2 // 以第0个元素结尾的最大子数组和
maxSum = nums[0] = -2 // 全局最大子数组和 - 步骤1:i=1, nums[1]=1
1
2
3
4
5
6
7
8
9
10
11
12
13当前元素: 1
决策:是将1加入已有子数组[-2],还是以1开始新的子数组?
- 选项1:加入已有子数组:currentSum + 1 = -2 + 1 = -1
- 选项2:开始新子数组:1
比较:1 > -1,所以选择选项2
更新:
currentSum = 1 // 以第1个元素结尾的最大子数组和
maxSum = max(-2, 1) = 1 // 更新全局最大值
当前状态:
以位置1结尾的最大子数组: [1],和为1
全局最大子数组: [1],和为1 - 步骤2:i=2, nums[2]=-3
1
2
3
4
5
6
7
8
9
10
11
12
13当前元素: -3
决策:是将-3加入已有子数组[1],还是以-3开始新的子数组?
- 选项1:加入已有子数组:currentSum + (-3) = 1 - 3 = -2
- 选项2:开始新子数组:-3
比较:-2 > -3,所以选择选项1
更新:
currentSum = -2 // 以第2个元素结尾的最大子数组和
maxSum = max(1, -2) = 1 // 全局最大值不变
当前状态:
以位置2结尾的最大子数组: [1, -3],和为-2
全局最大子数组: [1],和为1 - 步骤3:i=3, nums[3]=4
1
2
3
4
5
6
7
8
9
10
11
12
13当前元素: 4
决策:是将4加入已有子数组[1, -3],还是以4开始新的子数组?
- 选项1:加入已有子数组:currentSum + 4 = -2 + 4 = 2
- 选项2:开始新子数组:4
比较:4 > 2,所以选择选项2
更新:
currentSum = 4 // 以第3个元素结尾的最大子数组和
maxSum = max(1, 4) = 4 // 更新全局最大值
当前状态:
以位置3结尾的最大子数组: [4],和为4
全局最大子数组: [4],和为4 - 步骤4:i=4, nums[4]=-1
1
2
3
4
5
6
7
8
9
10
11
12
13当前元素: -1
决策:是将-1加入已有子数组[4],还是以-1开始新的子数组?
- 选项1:加入已有子数组:currentSum + (-1) = 4 - 1 = 3
- 选项2:开始新子数组:-1
比较:3 > -1,所以选择选项1
更新:
currentSum = 3 // 以第4个元素结尾的最大子数组和
maxSum = max(4, 3) = 4 // 全局最大值不变
当前状态:
以位置4结尾的最大子数组: [4, -1],和为3
全局最大子数组: [4],和为4 - 步骤5:i=5, nums[5]=2
1
2
3
4
5
6
7
8
9
10
11
12
13当前元素: 2
决策:是将2加入已有子数组[4, -1],还是以2开始新的子数组?
- 选项1:加入已有子数组:currentSum + 2 = 3 + 2 = 5
- 选项2:开始新子数组:2
比较:5 > 2,所以选择选项1
更新:
currentSum = 5 // 以第5个元素结尾的最大子数组和
maxSum = max(4, 5) = 5 // 更新全局最大值
当前状态:
以位置5结尾的最大子数组: [4, -1, 2],和为5
全局最大子数组: [4, -1, 2],和为5 - 步骤6:i=6, nums[6]=1
1
2
3
4
5
6
7
8
9
10
11
12
13当前元素: 1
决策:是将1加入已有子数组[4, -1, 2],还是以1开始新的子数组?
- 选项1:加入已有子数组:currentSum + 1 = 5 + 1 = 6
- 选项2:开始新子数组:1
比较:6 > 1,所以选择选项1
更新:
currentSum = 6 // 以第6个元素结尾的最大子数组和
maxSum = max(5, 6) = 6 // 更新全局最大值
当前状态:
以位置6结尾的最大子数组: [4, -1, 2, 1],和为6
全局最大子数组: [4, -1, 2, 1],和为6 - 步骤7:i=7, nums[7]=-5
1
2
3
4
5
6
7
8
9
10
11
12
13当前元素: -5
决策:是将-5加入已有子数组[4, -1, 2, 1],还是以-5开始新的子数组?
- 选项1:加入已有子数组:currentSum + (-5) = 6 - 5 = 1
- 选项2:开始新子数组:-5
比较:1 > -5,所以选择选项1
更新:
currentSum = 1 // 以第7个元素结尾的最大子数组和
maxSum = max(6, 1) = 6 // 全局最大值不变
当前状态:
以位置7结尾的最大子数组: [4, -1, 2, 1, -5],和为1
全局最大子数组: [4, -1, 2, 1],和为6 - 步骤8:i=8, nums[8]=4
1
2
3
4
5
6
7
8
9
10
11
12
13当前元素: 4
决策:是将4加入已有子数组[4, -1, 2, 1, -5],还是以4开始新的子数组?
- 选项1:加入已有子数组:currentSum + 4 = 1 + 4 = 5
- 选项2:开始新子数组:4
比较:5 > 4,所以选择选项1
更新:
currentSum = 5 // 以第8个元素结尾的最大子数组和
maxSum = max(6, 5) = 6 // 全局最大值不变
当前状态:
以位置8结尾的最大子数组: [4, -1, 2, 1, -5, 4],和为5
全局最大子数组: [4, -1, 2, 1],和为6 - 最终结果
1
2最大子数组和 = 6
对应的子数组 = [4, -1, 2, 1]
java版
1 | public class MaximumSubarray { |
✅ 说明:
- 时间复杂度:O(n),只需要遍历数组一次
- 空间复杂度:O(1),只使用了常数个额外变量
python版
1 | def maxSubArray(nums): |
Comment
匿名评论隐私政策









