关键词:数学 双指针
方法一:这个题目我一开始做不知道不能用除法。我做的:[ 用时: 12 m 12 s ] 用了除法 分类讨论
方法二:后来看了提示,双指针,两边各开始乘。
方法三:然后又看了答案可以节省空间。
题目:按规则计算统计结果
方法一:
用了除法 分类讨论
思路:
统计是否有零,不然没法除。
count_0//如果有0,那么true
求所有数的乘积:
res记录所有数(除了第一个遇到的0)的乘积结果。
如果只有一个0,那么除了它以外的数的乘积就是res。
如果有超过一个0,那么全部结果都是0。
for(const auto&x:arrayA){if(x==0&&count_0==0){count_0++;continue;}res*=x;}
求结果:
如果没有0,那么正常除。
如果有0,则0那个位置的结果就是res,除了0以外的数的结果都是0。
for(const auto&x:arrayA){if(count_0==0)arrayB.push_back(res/x);else{if(x==0)arrayB.push_back(res);elsearrayB.push_back(0); }}
复杂度计算:
时间复杂度O(n)
空间复杂度O(1)
代码:
class Solution {
public:vector<int> statisticalResult(vector<int>& arrayA) {int res=1;int count_0=0;for(const auto&x:arrayA){if(x==0&&count_0==0){count_0++;continue;}res*=x;}vector<int> arrayB;for(const auto&x:arrayA){if(count_0==0)arrayB.push_back(res/x);else{if(x==0)arrayB.push_back(res);elsearrayB.push_back(0); }}return arrayB;}
};
方法二:
看了答案的提示:左右两边各开始乘,得到从左到右和从右到左的两个向量
思路:
用两个向量记录从左到右累积和从右到左累积的结果。
然后求res的时候,左右各乘结果。
arrayA | 2 | 3 | 4 | 5 | 6 |
l2r | 2 | 2*3 | 2*3*4 | 2*3*4*5 | 2*3*4*5*6 |
r2l | 6 | 6*5 | 6*5*4 | 6*5*4*3 | 6*5*4*3*2 |
res | R2l[3] | l2r[0]*r2l[2] | l2r[1]*r2l[1] | l2r[2]*r2l[0] | l2r[3] |
复杂度计算:
时间复杂度O(n)
空间复杂度O(n) 2n,两个向量存累积结果
代码:
class Solution {
public:vector<int> statisticalResult(vector<int>& arrayA) {vector<int> res;if(arrayA.empty()) return res;if(arrayA.size()==1) return arrayA;vector<int> l2r,r2l;l2r.push_back(arrayA[0]);//初始化r2l.push_back(arrayA[arrayA.size()-1]);//初始化for(int i=1;i<arrayA.size();++i)//左到右累积{l2r.push_back(l2r[i-1]*arrayA[i]);}for(int i=1;i<arrayA.size();++i)//右到左累积{r2l.push_back(r2l[i-1]*arrayA[arrayA.size()-i-1]);}for(int i=0;i<arrayA.size();++i)//求res{int temp=1;if(i>0) temp*=l2r[i-1];//如果i=0,就不用左边if(i<arrayA.size()-1) temp*=r2l[arrayA.size()-i-2];//如果i在最右边,就不用右边res.push_back(temp);}return res;}
};
方法三:
看了k神的答案写的 和方法二一样但节省了空间
思路:
具体看k神的图解。
主要是先乘下三角,再乘上三角,即可。
下三角:
上三角:
复杂度计算:
时间复杂度O(n)
空间复杂度O(1)
代码:
class Solution {
public:vector<int> statisticalResult(vector<int>& arrayA) {vector<int> res;if(arrayA.empty()) return res;if(arrayA.size()==1) return arrayA;res.push_back(1);for(int i=1;i<arrayA.size();++i)//下三角{res.push_back(res[i-1]*arrayA[i-1]);}int temp=1;for(int i=arrayA.size()-2;i>=0;--i)//上三角{temp*=arrayA[i+1];res[i]*=temp;}return res;}
};