比如, 序列 [2,3,-2,4]
中乘积最大的子序列为 [2,3]
,其乘积为6
。
方法一:自己一开始写的方法比较麻烦。通过记录数组中元素为0的下标,然后以0为边界,分割数组,然后对每个分割后的数组分别求最大乘积子序列,最后在所有的分割数组的最大乘积子序列中取最大乘积。
class Solution {
public:
/**
* @param nums: a vector of integers
* @return: an integer
*/
int maxProduct(vector<int>& nums) {
// write your code here
int n=nums.size();
if(n==0) return 0;
if(n==1) return nums[0];
vector<int>zeroindex;
int i;
for(i=0;i<=n;i++){
if(i==n||nums[i]==0) zeroindex.push_back(i);
}
int len=zeroindex.size();
if(zeroindex[0]==n) return maxmulti(nums,0,n-1);
else{
int res=maxmulti(nums,0,zeroindex[0]-1);
for(int i=0;i<len-1;i++){
res=max(res,maxmulti(nums,zeroindex[i]+1,zeroindex[i+1]-1));
}
return res;
}
}
int maxmulti(vector<int>&nums,int left,int right){
if(left==right) return nums[left];
int res=1;
int count=0;
for(int i=left;i<=right;i++){
if(nums[i]<0){ count++;}
res*=nums[i];
}
if(count%2==0) return res;
else{
int itbeg,itend;
for(int i=left;i<=right;i++){
if(nums[i]<0){
itbeg=i;
break;
}
}
for(int i=right;i>=left;i--){
if(nums[i]<0){
itend=i;
break;
}
}
return max(maxmulti(nums,left,itend-1),maxmulti(nums,itbeg+1,right));
}
}
};
方法二:非常简洁的方法,访问到某个元素时,此时的最大乘积子序列,只有两种情况:一是该元素本省,二是该元素乘以“以前一点为末尾的子序列”。
class Solution {
public:
/**
* @param nums: a vector of integers
* @return: an integer
*/
int maxProduct(vector<int>& nums) {
int premax=nums[0];
int premin=nums[0];
int res=nums[0];
int n=nums.size();
for(int i=1;i<n;i++){
int temp1=premax;
int temp2=premin;
premax=max(nums[i],max(nums[i]*temp1,nums[i]*temp2));
premin=min(nums[i],min(nums[i]*temp1,nums[i]*temp2));
res=max(res,premax);
}
return res;
}
};