先上第一次通过的代码
// class Solution {
// public:
// vector<int> constructArr(vector<int>& a) {
// vector<int> b(a.size(),1);
// for(int i=0;i<a.size();++i){ //O(n^2),测试过了,但还是时间复杂度太高,怎么优化?不让用除法,确实
// //如果拿积合除以a[i]那就太容易了,有没有不用除法但可以这么简单的方法?
// //分区间?多大的区间合适?
// //
// for(int j=0;j<a.size();++j){
// if(j!=i){
// b[i]*=a[j];
// }
// }
// }
// return b;
// }
// };
//分区,用上下三角分成两个区,时间复杂度从n方掉到n
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
vector<int> b(a.size(),1),tmp(a.size(),1);
//vector<int> b,tmp; //用这个两行的程序代替上面的一行程序就会报错,问题出在哪?对角线上元素的初始化?
//b[0]=1;tmp[a.size()-1]=1;
//for(int i=0;i<a.size();++i){//这里给对角线元素初始化为1了,还是报错
// b[i]=1;
// tmp[i]=1; //暂时想不明白为什么只给b和tmp的对角线初始化会报错,走流程应该不会出现越界啊
//}
for(int i=1;i<a.size();++i){
b[i]=b[i-1]*a[i-1];
}
for(int j=a.size()-2;j>=0;--j){
tmp[j]=a[j+1]*tmp[j+1];
}
for(int i=0;i<a.size();++i){
b[i]*=tmp[i];
}
return b;
}
};
我最想不明白的是对于b数组的初始化,按照步骤走应该只需要给b[0]初始化就足够了啊
先看可以优化的点,tmp数组是多余的,只要一个变量tmp就可以搞定,不仅用单数组还能省去一个for循环
优化后写法
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
int n = a.size();
// 返回结果的计算
vector<int> b(n, 1);
// 从上到下,左下角的遍历
for (int i = 1; i < n; ++i)
{
b[i] *= b[i-1] * a[i-1];
}
int accu = 1; // 累计乘积的结果,用于和b[i] 来计算
// 从下到上,左上角的遍历
for (int i = n-2; i >=0 ; --i)
{
accu *= a[i+1];
b[i] *= accu;
}
return b;
}
};