原理
-
最大子段和问题定义
给定一个整数序列,要求找出该序列中具有最大和的连续子段(子数组)。例如,对于序列[-2, 1, -3, 4, -1, 2, 1, -5, 4]
,其最大子段和为6
,对应的子段是[4, -1, 2, 1]
。 -
动态规划思路及状态定义
- 状态定义:使用
dp[i]
表示以第i
个元素结尾的最大子段和。例如,dp[3]
就代表以序列中第 3 个元素结尾的连续子段能取得的最大和(这里序列索引从 0 开始计数)。 - 状态转移方程推导依据:对于每个元素
nums[i]
(i > 0
),有两种选择来构成以它结尾的最大子段和。一种是将当前元素nums[i]
加入到以nums[i - 1]
结尾的最大子段中(即dp[i - 1] + nums[i]
),另一种就是当前元素nums[i]
单独作为一个子段(即nums[i]
本身),取这两种情况中的较大值作为dp[i]
的值,也就是dp[i] = max(dp[i - 1] + nums[i], nums[i])
。因为要使得以nums[i]
结尾的子段和最大,要么接上前面的子段(前提是能使和更大),要么就自己单独成段(前面的子段和为负时,接上反而会使和变小)。 - 最终结果获取:在计算出所有以每个元素结尾的最大子段和
dp[i]
后,整个序列的最大子段和就是所有dp[i]
中的最大值,通过遍历dp
数组不断比较更新来找到这个最大值,存储在变量result
中并最终返回。
- 状态定义:使用
步骤
- 边界情况处理及初始化(函数开头部分)
- 首先判断输入的整数序列
nums
是否为空,如果为空(即nums.size() == 0
),按照题目要求直接返回0
,表示空序列的最大子段和为0
。 - 创建一个与输入序列
nums
长度相同的dp
向量(vector<int> dp(nums.size());
),用于存储以每个元素结尾的最大子段和。然后将dp[0]
初始化为nums[0]
,因为以第一个元素结尾的最大子段和就是这个元素本身,同时将result
也初始化为dp[0]
,此时resul
- 首先判断输入的整数序列