解法一:自底向上的递推DP
比如 nums[i] = -1,nums[0..i-1] 子数组的最大元素乘积为 10,那么能不能就说 nums[0..i] 的最大元素乘积为 max(-1, -1 * 10) = -1 呢?
其实不行,因为可能nums[0..i-1] 子数组的最小元素乘积为 -6,那么 nums[0..i] 的最大元素乘积应该为 max(-1, -1 * 10, -1 * -6) = 6`。
func maxProduct(nums []int) int {
// dp1[i]表示以nums[i]结尾的子数组的最小乘积
dp1 := make([]int, len(nums))
// dp2[i]表示以nums[i]结尾的子数组的最大乘积
dp2 := make([]int, len(nums))
// base case, 只有一个数可选
dp1[0] = nums[0]
dp2[0] = nums[0]
for i:=1; i<len(nums); i++{
dp1[i] = min(
nums[i],
min(dp1[i-1]*nums[i], dp2[i-1]*nums[i]),
)
dp2[i] = max(
// 只选择当前元素作为新的子数组
nums[i],
// 考虑到负负得正
// 若nums[i]为负数,那么就要和前i-1个数的最小乘积相乘
// 若nums[i]为整数,那么就要和前i-1个数的最大乘积相乘
// 不管怎么样,把二者都算一下取较大值,就不用判断正负情况了
max(dp1[i-1]*nums[i], dp2[i-1]*nums[i]),
)
}
res := math.MinInt
for _, v := range dp2{
res = max(res, v)
}
return res
}
func min(a, b int) int{
if a < b{
return a
}
return b
}
func max(a, b int) int{
if a > b{
return a
}
return b
}