0
点赞
收藏
分享

微信扫一扫

剑指 Offer 66. 构建乘积数组

王栩的文字 2022-02-04 阅读 64

题目描述:

分析:

这道题肯定不能使用暴力法,否则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;

    }
};
举报

相关推荐

0 条评论