给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字)。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
思路:
动态规划:
类似于最大子序列和的思想,不过本题说的是最大子数组,即中间必须要连续,而且存在负数,由于负负得正,即如果遍历到i的时候dp[i]保存当前的最大值,若nums[i]<0则dp[i]*nums[i+1]为最小值,同理,若dp[i]保存遍历到i的最小值,nums[i+1]为负,则dp[i]*nums[i+1]为最大值,所以本题需要两个dp数组,分别保存到当前的最大值与最小值
状态转移方程:
maxDP[i+1]=max(maxDP[i]*nums[i+1],nums[i+1],maxDp[i]*A[i+1])
minDP[i+1]=min(minDP[i]*nums[i+1],nums[i+1],minDp[i]*A[i+1])
初始maxDP[0]=minDP[0]=nums[0].
最后返回maxDP[nums.size()-1]即可。
优化:不使用dp数组,可以直接用两个整型变量保存当前最大值与最小值,遍历到最后输出最大值即可。
AC代码:(C++)
class Solution {
public:
int maxProduct(vector<int>& nums) {
int size = nums.size();
if (size == 0)
return 0;
else if (size == 1)
return nums[0];
int maxP = nums[0], minP = nums[0], ans = nums[0];
for (int i = 1; i < size; i++) {
int temp = maxP;
maxP = max(max(maxP * nums[i], nums[i]), minP * nums[i]);
minP = min(min(temp * nums[i], nums[i]), minP * nums[i]);
ans = max(maxP, ans);
}
return ans;
}
};