菜鸟笔记
提升您的技术认知

《剑指offer》构建乘积数组-ag真人游戏

阅读 : 255

题目描述:

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

解题思路:

观察下公式,你会发现,b[i]公式中没有a[i]项,也就是说如果可以使用除法,就可以用公式b[i]=a[0]a[1].....*a[n-1]/a[i]来计算b[i],但是题目要求不能使用,因此我们只能另想办法。

现在要求不能使用除法,只能用其他方法。一个直观的解法是用连乘n-1个数字得到b[i]。显然这个方法需要o(n*n)的时间复杂度。

好在还有更高效的算法。可以把b[i]=a[0]a[1].....a[i-1]a[i 1].....a[n-1]。看成a[0]a[1].....a[i-1]和a[i 1].....a[n-2]*a[n-1]两部分的乘积。

即通过a[i]项将b[i]分为两部分的乘积。效果如下图所示:

不妨设定c[i]=a[0]a[1]...a[i-1],d[i]=a[i 1]...a[n-2]a[n-1]。c[i]可以用自上而下的顺序计算出来,即c[i]=c[i-1]a[i-1]。类似的,d[i]可以用自下而上的顺序计算出来,即d[i]=d[i 1]a[i 1]。

如果还是不明白,没有关系,直接看下代码,细细体会下就懂了。

第一个for循环用来计算上图1范围的数,第二个for循环用来计算上图2范围的数。

代码实现(c )

class solution {
public:
    vector multiply(const vector& a) {
        int length = a.size();
        vector b(length);
        if(length <= 0){
            return b;
        }
        b[0] = 1;
        for(int i = 1; i < length; i  ){
            b[i] = b[i - 1] * a[i - 1];
        }
        int temp = 1;
        for(int i = length - 2; i >= 0; i--){
            temp *= a[i   1];
            b[i] *= temp;
        }
        return b;
    }
};

代码实现(python)

python可以利用reduce方法快速求解。

# -*- coding:utf-8 -*-
class solution:
    def multiply(self, a):
        # write code here
        b = []
        if len(a) == 0:
            return b
        else:
            for i in range(len(a)):
                tmp = a[i]
                a[i] = 1
                b.append(reduce(lambda x,y:x*y, a))
                a[i] = tmp
        return b
网站地图