主要思想
通过枚举 [以每一个元素为结尾的子数组] 来完备的枚举所有子数组,用dp数组在每一步维护所需的指标最优
例题
LeetCode 53. 最大子数组和
在nums数组中找出一个具有最大和的连续子数组(最少包含一个元素),返回其最大和
- dp[i]为:以nums[i]为结尾的子数组,能获得的最大和
- 对于每个nums[i],更新dp[i],如果前面连续一段子数组为正,则可以拼接,否则不拼接
LeetCode 918. 环形子数组的最大和
要求同上,但是nums数组此时是环形的
两种情况:
- 最大子数组不是环状的,同53题的答案
- 最大子数组成环,需要数组首尾的一部分拼接,可以转为sum-[非成环情况的最小子数组和]
即转化为求【最小子数组和】问题
LeetCode 1567. 乘积为正数的最长子数组长度
在nums数组中,求出其所有元素乘积为正数的最长子数组的长度
dp_pos[i]
维护以i元素为结尾的乘积为正的最长子数组长度,dp_neg[i]
维护以i元素为结尾的乘积为负的最长子数组长度- 当前数字为正,则
dp_pos[i]
源自dp_pos[i - 1]
,dp_neg[i]
取决于dp_neg[i - 1]
- 当前数字为负,则
dp_pos[i]
源自dp_neg[i - 1]
,dp_neg[i]
取决于dp_pos[i - 1]
- 注意当前数字为零时,
dp_pos[i]
、dp_pos[i]
都为0
LeetCode 152. 乘积最大子数组
在nums数组中找出一个具有最大乘积的连续子数组(最少包含一个元素),返回其最大乘积
- 由于存在负数,那么会导致最大的变最小的,最小的变最大的
- 同时维护最小与最大乘积:
dp_max[i]
维护以i元素为结尾的子数组最大乘积,dp_min[i]
维护以i元素为结尾的子数组最小乘积