1. 程式人生 > 實用技巧 >[LeetCode] 238. Product of Array Except Self(陣列除自身元素外的乘積)

[LeetCode] 238. Product of Array Except Self(陣列除自身元素外的乘積)

Description

Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all elements of nums except nums[i].
給一個數組 nums(長度大於 1),返回一個數組 output

,其中 output[i] 等於 nums 陣列內除 nums[i] 外所有元素的乘積。

Example

Input:  [1,2,3,4]
Output: [24,12,8,6]

Constraint

It's guaranteed that the product of the elements of any prefix or suffix of the array (including the whold array) fits in a 32 bit integer.
輸入保證陣列的任何子陣列的乘積結果都在 32 位整數範圍內。

Note

Please solve it without division

and in O(N).
不使用除法並在 \(O(N)\) 內解決它。

Follow up

Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)
你能使用常數額外空間解答嗎(用於輸出的陣列不計入空間複雜度分析)。

Solution

假設陣列有 4 個元素 [a, b, c, d],那麼最後的結果應該是 [bcd, acd, abd, abc],對於每個元素,我們以該元素為界,將其分為前半部分和後半部分,沒有的部分用 1 填充,得到如下結果:

  • 前半部分:[1, a, ab, abc]

  • 後半部分:[bcd, cd, d, 1]

不難看出,分別做一次字首積和一次後綴積,再將二者相乘,即可得到最終結果,程式碼如下:

class Solution {
    fun productExceptSelf(nums: IntArray): IntArray {
        // 字首積
        val prefix = IntArray(nums.size)
        prefix[0] = 1
        for (i in 1..nums.lastIndex) {
            prefix[i] = nums[i - 1] * prefix[i - 1]
        }

        // 字尾積
        val suffix = IntArray(nums.size)
        suffix[nums.lastIndex] = 1
        for (i in nums.lastIndex - 1 downTo 0) {
            suffix[i] = nums[i + 1] * suffix[i + 1]
        }

        // 結果
        val result = IntArray(nums.size)
        for (i in nums.indices) {
            result[i] = prefix[i] * suffix[i]
        }

        return result
    }
}

至於 Follow up 裡的常數額外空間,我在 discussion 裡找了一下,大概思路就是隻保留一個字首積陣列,字尾積則是邊生成邊乘上去,這樣可以壓縮掉兩個額外陣列空間,只有返回陣列的空間了,程式碼如下:

class Solution {
    fun productExceptSelf(nums: IntArray): IntArray {
        val result = IntArray(nums.size)
        result[0] = 1
        for (i in 1..nums.lastIndex) {
            result[i] = result[i - 1] * nums[i - 1]
        }
        var suffix = 1
        for (i in nums.indices.reversed()) {
            result[i] *= suffix
            suffix *= nums[i]
        }

        return result
    }
}