《剑指offer》-构建乘积数组

题目描述

给定一个数组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]。不能使用除法。


解法:

方法1:暴力解法。

1)假设A=[1,2,3],那么B[0] = A[1]*A[2]   B[1] = A[0]*A[2]   B[2] = A[0]*A[1]

2)可以发现规律,B[i]就等于A的连乘,除掉A[i]那个数

3)两个嵌套循环,很容易就写出来,复杂度为O(N^2),内层循环用个continue去掉相等的情况就可以了

class Solution {
public:
    vector<int> multiply(const vector<int>& A) {
        int len = A.size();
        if(len == 0) return A;
        vector<int> B(len, 1);
        
        /暴力破解法
        for(int i = 0; i < len; i++) {
            int temp = 1;
            for(int j = 0; j < len; j++) {
                if(i == j) continue;
                temp *= A[j];
            }
            B[i] = temp;
        }
        return B;        
    }
};
方法2:优雅的解法

1)令C[i] = A[0]*A[1]*...*A[i-1],那么我们可以得到,C[i] = C[i-1] * A[i-1],因为C[i-1] = A[0]*A[1]*...*A[i-3]*A[]i-2]

2)令D[i] = A[i+1]*...*A[n-1],那么我们可以得到,D[i] = D[i+1]*A[i+1],因为D[i+1] = A[i+2]*...*A[n-1]

3 ) B[i] = C[i]*D[i]

4 ) 这需要确定1)和2)中循环计算C和D时候的循环条件,1)中,最小为i-1,所以,i必须从1开始,且小于数组长度len,取不到;同理2)中,最大为i+1,因此只能i小于len-2,否则数组将越界,最小i可以取到0下标。

class Solution {
public:
    vector<int> multiply(const vector<int>& A) {
        int len = A.size();
        if(len == 0) return A;
        vector<int> B(len, 1);
        ///优美的解法
    	vector<int> front(len, 1);
        vector<int> back(len, 1);
        vector<int> B(len, 1);
        for(int i = 1; i < len; i++) {
            front[i] = front[i-1] * A[i-1];
        }
        for(int i = len - 2; i >= 0; i--) {
            back[i] = back[i+1] * A[i+1];
        }
        for(int i = 0; i < len; i++) {
            B[i] = front[i] * back[i];
        }
        return B;       
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值