Leetcode 152 Maxinum Product Subarray
题目原文
Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4]
,
the contiguous subarray [2,3]
has the largest product = 6
.
题意分析
给一组数据,求一个连续的子数组,使得子数组的乘积最大,输出这个最大值。
解法分析
本题如果采用暴力解法,复杂度为O(n^2),因此需要寻求O(n)的解法。本题采用动态规划的方法,令以第i个元素为最后一个元素的最大乘积数组的最大乘积为maxP[i],如果nums[i]为正数,则maxP[i]=max(maxP[i],maxP[i-1]*nums[i]),而当nums[i]<0时情况不同,此时maxP[i]与minP[i-1]有关。这种递归式会受nums[i]影响的动态规划方法需要两个数组来存储动态规划的中间结果。由于两组递归式都只与前一个元素相关,所以不需要用数组存储DP中间值,只需要分别用一个变量来存储。C++代码如下:
class Solution {
public:
int maxProduct(vector<int>& nums) {
int n=nums.size();
if(n==1)
return nums[0];
if(n==0)
return 0;
int i;
int res=nums[0];
int lastMin=nums[0],nextMin;
int lastMax=nums[0],nextMax;
for(i=1;i<n;i++){
if(nums[i]<0){
nextMin=min(nums[i],lastMax*nums[i]);
nextMax=max(nums[i],lastMin*nums[i]);
}
else{
nextMin=min(nums[i],lastMin*nums[i]);
nextMax=max(nums[i],lastMax*nums[i]);
}
res=max(nextMax,res);
lastMin=nextMin;
lastMax=nextMax;
}
return res;
}
};
上诉代码可以优化如下:
class Solution {
public:
int maxProduct(vector<int>& nums) {
int maxProduct = nums[0];
int minProduct = nums[0];
int result = nums[0];
for(int i = 1; i < nums.size(); i++)
{
if(nums[i] < 0)
swap(maxProduct, minProduct);
maxProduct = max(maxProduct * nums[i], nums[i]);
minProduct = min(minProduct * nums[i], nums[i]);
result = max(maxProduct, result);
}
return result;
}
};
递归式左右用同一个变量存储,当遇到nums[i]<0时,只需swap(maxProdunct,minProduct)。