剑指offer——构建乘积数组(C++)

7 篇文章 0 订阅
4 篇文章 0 订阅

题目描述:给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1], 其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1],不能使用除法。

对于这个题目,如果没有“不能使用除法”这个规定,可以通过计算A[0]A[1]A[i]…*A[n-1]除以A[i]来计算B[i]的值(考虑A[i]是否为0的情况)
现在多了这个条件,我们可以这么考虑,如下面的图

对以上图片做描述:可以看出,B[i]为 A数组除了A[i]外的所有元素的乘积。我们可以画出如上的图。比如上图的B[0]原本应等于除A[0]外 A数组的所有元素的乘积,也就是B[0]=A[1]*A[2]*A[3]*A[4] …*A[n-1],再比如B[1]=A[0]*A[2]*A[3]*A[4] …*A[n-1],B[3]=A[1]*A[2]*A[4] …*A[n-1]等等,都会出来一条分界线,如上图,那我们就可以以这条分界线为基准,将B[i]划分为两部分:分界线之前和分界线之后,再将二者相乘,不就是我们所求的B[i]吗?
至于为什么对角线是1,可以这么看:B[0] = 1乘以分界线后面的部分。
B[1] = A[0]乘以1再乘以后面的部分,也就是B[1]=A[0]*B[0],以此类推。
到最后一个B[n-1] = A[0]*A[1] …*A[n-2]。需要注意每一个1只是在相应的行上设想成1,因为本身不参与该行的乘积(乘积结果为B[i])
因此,会有两个循环,第一次循环算左边的下三角(蓝色部分),第二次循环算右边的上三角(绿色部分),最后结果为二者相乘。
注意到
第一次循环应从【1,n-1】(因为B[0] = 1乘以后面的部分,只需要算后面的部分就可以可以了),第二次循环应从【n-2,0】(因为B[n-1]等于前面的部分乘以1,只需要算前面的部分就可以了)
接下来附上代码

class Solution {
public:
    vector<int> multiply(const vector<int>& A) {
        vector<int> B(A.size());
        if(A.size() <= 0){
            return B;
        }
        
        caculate(B,A);
        return B;
    }
    void caculate(vector<int> &B, const vector<int>& A){
        //下三角
        B[0] = 1;
        for(int i = 1; i < A.size(); ++i){
            B[i] = A[i - 1] * B[i - 1];
        }
        
        int temp = 1;
        //上三角
        for(int j = A.size() - 2; j >= 0; --j){
            temp *= A[j + 1];
            B[j] *= temp;
        }
        return;
    }
};


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值