《Leetcode》238. 除自身以外數組的乘積

給你一個長度爲 n 的整數數組 nums,其中 n > 1,返回輸出數組 output ,其中 output[i] 等於 nums 中除 nums[i] 之外其餘各元素的乘積。

示例:

輸入: [1,2,3,4]
輸出: [24,12,8,6]

提示:題目數據保證數組之中任意元素的全部前綴元素和後綴(甚至是整個數組)的乘積都在 32 位整數範圍內。

說明: 請不要使用除法,且在 O(n) 時間複雜度內完成此題

進階:
你可以在常數空間複雜度內完成這個題目嗎?( 出於對空間複雜度分析的目的,輸出數組不被視爲額外空間。)

思路:

1、題目分析

題目本身比較好理解,就是在除了該位置外,把這個數組中其餘的元素全部乘起來就可以了。

2、解題分析

這個題目提示用到前綴和後綴,這個時候就可以考慮用這個方法去解題。每個位置的結果就是用這個位置左邊所有元素的乘積*右邊所有元素的乘積。所有關鍵的問題是怎麼去找左右兩邊元素的乘積。這個時候可以聲明一個列表用前綴和的方法去做。這個列表保存的是每個位置左邊所有元素之積。那麼左邊之積有了,就差右邊了,此時可以有兩種方法去解決:①和左邊元素一樣在聲明一個列表去保存右邊所有元素之積,這樣空間複雜度會變成O(n);②爲了簡化空間複雜度,我們可以設置一個變量,這個變量在每次循環遍歷列表的時候不斷的去更新右邊元素之積。這樣空間複雜度就降低爲O(1)。接下來代碼示例一下:

class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:

        #聲明列表長度
        length = len(nums)
        #初始左側前綴積的數組
        answer = [0]*length
        # answer[i] 表示索引 i 左側所有元素的乘積
        # 因爲索引爲 '0' 的元素左側沒有元素, 所以 answer[0] = 1
        answer[0] = 1
        for i in range(1, length):
            answer[i] = nums[i - 1] * answer[i - 1]
        
        print(answer) # [1, 1, 2, 6]
        # R 爲右側所有元素的乘積
        # 剛開始右邊沒有元素,所以 R = 1
        R = 1
        for i in range(length-1,-1,-1):
            # 對於索引 i,左邊的乘積爲 answer[i],右邊的乘積爲 R
            answer[i] = answer[i] * R
            # R 需要包含右邊所有的乘積,所以計算下一個結果時需要將當前值乘到 R 上
            R *= nums[i]
        
        return answer

畫圖展示:

總結:數組問題簡化成前綴和和前綴積在空間複雜度上面就降低了很多。 關鍵就是找準前綴和(積)初始化的值就是answer[0]。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章