题目描述
知识点
动态规划
结果
实现
码前思考
- 这个题目最大的陷阱就是很容易掉到和最大子数组和的陷阱里面。我们考虑
[-2,1,-2]
这种情况就应该知道这并不简简单单是最大子数组和那么简单的事情了; - 这里还是使用到了最大子数组和中,
i
位置的情况是由i-1
号位置所决定的这种最优子结构问题,但是在这里,由于在计算i-1
时,是不可以去看i
及其后面的数字的符号的,所以我们需要存储两个值,i-1
位置的最大正数乘积maxPos和最小负数乘积minNeg,然后到i
时,i
根据自身的符号去选择到底使用哪个,这里面有一堆的情况。。。 - 由于并不是任何时候都有maxPos和minNeg的,所以我们要初始化maxPos=-1,minNeg=1来处理这种情况;
- 对于0这个特殊值也要进行考虑。。。
代码实现
//由于符号的原因,需要记录两个,一个是最大正值,一个是最小负值
class Solution {
public:
int maxProduct(vector<int>& nums) {
int sz = nums.size();
//这样初始化是为了标记存不存在的
vector<int> maxPos(sz+1,-1);
vector<int> minNeg(sz+1,1);
int product = INT_MIN;
//初始化
product = nums[0];
if(nums[0]>0){
maxPos[0]=nums[0];
}else if(nums[0]<0){
minNeg[0]=nums[0];
}else{
//如果是0就不管,保持初始时话
}
//接下来进行遍历
for(int i=1;i<sz;i++){
//先无脑比较单个的大小
product = max(nums[i],product);
if(nums[i]>0){
if(maxPos[i-1]!=-1){
maxPos[i] = maxPos[i-1]*nums[i];
product = max(maxPos[i],product);
}else{
maxPos[i] = nums[i];
}
if(minNeg[i-1]!=1){
minNeg[i] = minNeg[i-1]*nums[i];
}
}else if(nums[i]<0){
if(minNeg[i-1]!=1){
maxPos[i] = minNeg[i-1]*nums[i];
product = max(maxPos[i],product);
}
if(maxPos[i-1]!=-1){
minNeg[i] = maxPos[i-1]*nums[i];
}else{
minNeg[i] = nums[i];
}
}else{
//为0时
product = max(0,product);
}
cout<<i<<" maxPos: "<<maxPos[i]<<endl;
cout<<i<<" minNeg: "<<minNeg[i]<<endl;
}
return product;
}
};
码后反思
- 这个时间和空间复杂度都不太好啊。。。
- 下面是大佬们的题解
- 我的代码的主要冗余的地方在于考虑了正数和负数,而且其实并不需要两个数组,只需要两个变量就好了。。。当然,空间它不值钱。。。