题目描述:
分析:
这道题肯定不能使用暴力法,否则100000*100000的时间复杂度肯定会超时。有没有什么别的思路呢?仔细观察可以发现,对于B[i]来说,它和B[i-1]有着极其紧密的关系,B[i]=A[0]*A[1]*A[2]*.....*A[i-1]*A[i+1]*A[i+2]*........*A[n-2]*A[n-1]
B[i-1]=A[0]*A[1]*A[2]*.....*A[i-3]*A[i-2]*A[i]*A[i+1]*........*A[n-2]*A[n-1]
可以看到B[i]乘积形式的左边A[0]*A[1]*A[2]*.....*A[i-1] 和B[i-1]乘积形式的左边A[0]*A[1]*A[2]*.....*A[i-3]*A[i-2]相比,只差了一个A[i-1]
B[i]乘积形式的右边A[i+1]*A[i+2]*........*A[n-2]*A[n-1]和B[i-1]乘积形式的右边A[i]*A[i+1]*........*A[n-2]*A[n-1]相比,只差了一个A[i+1]
由此,我们可以想到,B[i]的可以由左右两部分相乘组成,即B[i]=x[i]*y[i],其中,x[i]表示A[0]*A[1]*A[2]*.....*A[i-1],y[i]表示A[i+1]*A[i+2]*........*A[n-2]*A[n-1]。
这样的话,就可以发现x[i]和x[i-1]之间的关系,x[i]=x[i-1]*A[i-1]。因此,可以从x[0]开始,通过累乘的方式,得到所有x[i],(y[i]也同理)
故最后计算B[i]时,只需要B[i]=x[i]*y[i]即可。
代码如下:
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
// 得到数组的大小n
int n=a.size();
// 定义一个长度为n的数组res
vector<int> res(n);
if(n==0) return res;
// x和y分别存储b[i]的左半边乘积和右半边乘积
int x[n],y[n];
// temp代表累乘积,初始为1
int temp=1;
for(int i=0;i<n;i++)
{
// 从0开始,依次计算各个数的累乘积
// temp代表0~i-1所有数的累乘积
x[i]=temp;
// temp乘以a[i],继续扩大
temp=temp*a[i];
}
temp=1;
for(int i=n-1;i>=0;i--)
{
// 从n-1开始,以此计算右半边的累乘积
// temp代表i+1~n-1所有数的累乘积
y[i]=temp;
temp=temp*a[i];
}
// 最终的B[i],就是x[i]*y[i]
for(int i=0;i<n;i++)
res[i]=x[i]*y[i];
return res;
}
};