1、#628 三个数的最大乘积 #
时间复杂度o(nlogn),空间复杂度o(logn)(注意别忘了排序还有空间复杂度)
小结:能用暴力算法的肯定不行,一般几个for循环后都会超出时间限制。要想那种遍历一遍就可以的方法,比如哈希表数据结构,或者想利用排序,虽然是o(nlogn),但起码比n³要好。
注意方法思路:不用暴力算法后,确定好某种其他方法,就按照这种方法的思路去写一些过程或者穷举出样例,这样去找规律,然后去设置代码条件。
穷举时要么举一般的普通的例子,如果发现得到的规律不能够涵盖所有,要把所有特点的例子全面的都穷举出来。
如果发现运行后不通过,某一些例子还不行,那就再改或者加一些条件,把其他没有涵盖到的特例给用条件再筛出即可。
但注意此题:当观察到,条件其实非常非常多,而结果只有两种情况,此时条件可以全部忽略掉,用一个我们要的最终结果:最大值max(a,b)来去限制这两个结果,而不是全靠用条件确定限制结果。
所以思考方式:要么用条件约束可能的结果,要么用最终结果约束可能的结果,比如求最大值。关键是:大的思路要正确,再细想。
①解题:先排序,如果都为非负数和非负数,最大值均为最大三位的成绩;如果有正数有负数,最大值可能为最小两位负数与最大正数的乘积,也可能为三位最大正数的乘积。只需要求出这两种值的最大值即可。
class Solution {
public:
int maximumProduct(vector<int>& nums) {
int n=nums.size()-1;
sort(nums.begin(),nums.end());
return max(nums[0]*nums[1]*nums[n],nums[n-2]*nums[n-1]*nums[n]);
}
};
/*我:
class Solution {
public:
int maximumProduct(vector<int>& nums) {
int n=nums.size()-1;
sort(nums.begin(),nums.end());
if((nums[n-2]>0)&&(nums[1]<0)){
if(nums[0]*nums[1]*nums[n]<nums[n-2]*nums[n-1]*nums[n])
return nums[n-2]*nums[n-1]*nums[n];
else return nums[0]*nums[1]*nums[n];
}
if(((nums[n-2]<0)&&(nums[n]<0)))return nums[n-2]*nums[n-1]*nums[n];
if((nums[n-2]==0)||((nums[n-2]<0)&&(nums[n]>0)))return nums[0]*nums[1]*nums[n];
else return nums[n-2]*nums[n-1]*nums[n];
}
};*/
/*我:暴力求法:
class Solution {
public:
int maximumProduct(vector<int>& nums) {
int max=nums[0]*nums[1]*nums[2],pdt=0,n=nums.size();
for(int i=0;i<n-2;i++){
for(int j=i+1;j<n-1;j++){
for(int k=j+1;k<n;k++){
pdt=nums[i]*nums[j]*nums[k];
if(max<pdt)max=pdt;
}
}
}
return max;
}
};*/
方法二: