LeetCode练习-简单 -152. 乘积最大子数组(动态规划)
给你一个整数数组 nums
,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
分析:
dp原理:dp[i,0] =
if nums[i]>=0
dp[i-1,0] + nums[i]
else
dp[i-1,1] + nums[i]
思路一:暴力
时间复杂度: O(2^N)
空间复杂度: O(N)
双重循环把每一种可能都考虑到,记下来所有乘积的最大值返回
func maxProduct(nums []int) int {
max:=-87654321
for i:=0;i<len(nums);i++{
var res=1
for j:=i;j<len(nums);j++{
res=nums[j]*res
if res>max {
max=res
}
}
}
return max
}
思路二:动态规划
时间复杂度: O(N)
空间复杂度: O(1)
动态规划思想:
1.逆推,如图,到-2这个这个位置时先找到找寻-2这个点前面所有情况中的最大值,记录下来再加进存在-2情况作比较
2.由于存在负数会引入min(最小值相对应)连续时可进行变换
3.如果该值被抛弃则max或min都会为nums[i]
max=getMax(getMax(mi*nums[i],nums[i]),ma*nums[i])
min=getMin(getMin(ma*nums[i],nums[i]),mi*nums[i])
func maxProduct(nums []int) int {
ans,max,min,ma,mi:=nums[0],nums[0],nums[0],nums[0],nums[0]
for i:=1;i<len(nums);i++ {
ma,mi=max,min
max=getMax(getMax(mi*nums[i],nums[i]),ma*nums[i])
min=getMin(getMin(ma*nums[i],nums[i]),mi*nums[i])
ans=getMax(ans,max)
}
return ans
}
func getMax(a,b int) int {
if a>b {
return a
}
return b
}
func getMin(a,b int) int {
if a<b {
return a
}
return b
}