生病了两天,好不容易病好了,挑了道看上去比较简单的题,没想到这么不好对付,用了足足三个小时。
第一次提交时候,什么都没想就用了二重循环,结果显示TLE,仔细查过才知道是超时的意思...没办法开始各种改代码...
我的想法是这样的,考虑由0分割开来的各个部分(如果没有0就说明整个数组是一个部分),对于这样的部分来说,若
含有偶数个负数,那最大乘积就是所有元素之积,若含有奇数个(非1)负数,那最大元素一定是所有元素乘积除以第一次
或最后一次出现出现负数时候的元素乘积,举个例子,若有数组A B C D EFG,其中B为负数,则这一段的最大乘积一
定为A到G的乘积除以A到B的成绩或除以B到G的乘积,基于以上思想,我完成了下面的代码,一次从前往后找,一次从
后往前找,找到最大乘积。有几个关键地方要特别注意,现收集如下:
1.若是-2 0 -2这种情况该怎么办,最大乘积为-2,首次出现乘积也为-2,-2/-2等于1
2.若是有1111-2这种情况怎么办
3.若最大值小于零怎么办
最后经过调试,完成了以下代码,写的比较烂,但是功能都无错的实现了。
class Solution {
public:
int maxProduct(int A[], int n) {
int product,first_product = 1,first_flag = 1,first_time=0,sign=0;
int last_product = 1,last_flag = 1,last_time=0,temp_product = 1;
product = A[0];
if(!(n-1)*n) return product;
for(int i = 0;i < n;i++){
if(A[i]==1) sign=1;
if(A[i]==0){
if(first_time%2){temp_product = temp_product/first_product;if(temp_product==1&&!sign) temp_product*=first_product;}
if(temp_product>product&&i!=0) product = temp_product;
if(product<0) product = 0;
first_flag = 1;
first_time = 0;
temp_product = 1;
first_product = 1;
sign = 0;
}
else{
temp_product*=A[i];
if(A[i]<0){
if(first_flag){
first_product = temp_product;
first_flag = 0;
}
first_time++;
}
if(i==n-1){
if(first_time%2){temp_product = temp_product/first_product;if(temp_product==1&&!sign) temp_product*=first_product;}
if(temp_product>product) product = temp_product;
temp_product = 1;
sign = 0;
}
}
}
for(int i = n-1;i >= 0;i--){
if(A[i]==0){
if(last_time%2){temp_product = temp_product/last_product;if(temp_product==1&&!sign) temp_product*=last_product;}
if(temp_product>product&&i!=n-1) product = temp_product;
if(product<0) product = 0;
last_flag = 1;
last_time = 0;
temp_product = 1;
last_product = 1;
sign = 0;
}
else{
temp_product*=A[i];
if(A[i]<0){
if(last_flag){
last_product = temp_product;
last_flag = 0;
}
last_time++;
}
if(i==0){
if(last_time%2){temp_product = temp_product/last_product;if(temp_product==1&&!sign) temp_product*=last_product;};
if(temp_product>product) product = temp_product;
}
}
}
return product;
}
};