Given an integer array nums
, find the contiguous subarray within an array (containing at least one number) which has the largest product.
Example 1:
Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:
Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
题意:给定一个数组,求乘积最大的连续子序列。
方法一:动态规划。
二维数组Dp[i]记录状态,表示以nums[i] 结尾的子序列的状态。其中 Dp[i][0] 记录最大值,Dp[i][1] 记录最小值,
状态转移方程为:
class Solution {
public:
int maxProduct(vector<int>& nums) {
if(nums.size() == 0)
return 0;
vector<vector<int>> dp(nums.size());
int max = nums[0];
dp[0].push_back(nums[0]);
dp[0].push_back(nums[0]);
for(int i = 1; i< nums.size(); i++)
{
pair<int,int> data = minmax({nums[i], nums[i]* dp[i-1][0], nums[i]* dp[i-1][1]});
dp[i].push_back(data.second);
dp[i].push_back(data.first);
if(max < dp[i][0])
max = dp[i][0];
}
return max;
}
};
方法二:动态规划 + 状态压缩
动态规划的思路同上。
使用preMax, preMin两个变量记录上一个状态的最大值和最小值,而不是使用二维数组,从而节省内存空间。
class Solution {
public:
int maxProduct(vector<int>& nums) {
if(nums.size() == 0)
return 0;
int max = nums[0];
int preMax = nums[0];
int preMin = nums[0];
for(int i = 1; i< nums.size(); i++)
{
pair<int,int> data = minmax({nums[i], nums[i]* preMax, nums[i]* preMin});
preMin = data.first;
preMax = data.second;
if(max < preMax)
max = preMax;
}
return max;
}
};