劍指offer | 面試題66:構建乘積數組

轉載本文章請標明作者和出處
本文出自《Darwin的程序空間》
本文題目和部分解題思路來源自《劍指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,2,3,4,5]
    輸出: [120,60,40,30,24]
    
  • 提示

    所有元素乘積之和不會溢出 32 位整數
    a.length <= 100000
    

解題分析

題目要求不能使用除法,所以你求出所有的數的乘積,然後再除以每個數構結果集的第一想法就流產了;

這道題就是要求結果數組上的每一個數,都是原數組除了這個位置的數的乘積;

在這裏插入圖片描述
以第二個節點爲例,其實就是這個當前節點元素所有在原數組左邊的元素乘積乘以原數組在這個索引右邊的元素乘積;

那麼我們的做法就是,先把每一個元素的左邊的乘積和右邊的乘積都算出來,然後新的數組的元素就等於這個元素左邊的乘積加上右邊的乘積;

如上圖中的示例,所有左邊的乘積爲:
在這裏插入圖片描述
這個數組上所有的位置上的數都是原數組此位置上的書的左邊的所有元素的乘積

如上圖中的示例,所有右邊的乘積爲:
在這裏插入圖片描述
這個數組上所有的位置上的數都是原數組此位置上的書的右邊的所有元素的乘積,

最後所求數組即使這兩個數據的相同位置索引的乘積構成的新數組;

在這裏插入圖片描述
然後我們使用累乘,少定義兩個數組即可完成最優算法;

代碼

ps:這裏筆者使用的jdk爲1.8、Python3.7版本

  • java實現
class Solution {
    public int[] constructArr(int[] a) {
        if (Objects.isNull(a) || a.length == 0) {
            return new int[]{};
        }
        int[] res = new int[a.length];
        int left = 1;
        for (int i = 0; i < res.length; i++) {
            res[i] =left;
            left *= a[i];
        }
        int right = 1;
        for (int i = res.length - 1; i >= 0; i--) {
            res[i] *= right;
            right *= a[i];
        }
        return res;
    }
}
  • Python實現
class Solution:
    def constructArr(self, a: List[int]) -> List[int]:
        if a is None or len(a) == 0:
            return []
        res = [None] * len(a)
        left = 1
        for i in range(len(a)):
            res[i] = left
            left *= a[i]
        right = 1
        for i in reversed(range(len(a))):
            res[i] *= right
            right *= a[i]
        return res


喜歡的朋友可以加我的個人微信,我們一起進步
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章