1. 程式人生 > >LeetCode014 : 除自身以外陣列的乘積

LeetCode014 : 除自身以外陣列的乘積

在這裡插入圖片描述

一、寫在前面

LeetCode 第十三題反轉字串傳輸門:LeetCode013 : 反轉字串中的單詞 III
今天給大家分享的是LeetCode 陣列與字串 第十四題: 除自身以外陣列的乘積,為面試而生,期待你的加入。
“Use the utility in the API is recommended in the project. But if you use it in an interview, you will definitely fail .”

二、今日題目

給定長度為 n 的整數陣列 nums,其中 n > 1,返回輸出陣列 output ,其中 output[i] 等於 nums 中除 nums[i] 之外其餘各元素的乘積。
示例:

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

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

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

三、 分析

這個題目,第一眼很簡單,不就是去除一個元素,求其他元素積嗎,來兩個for巢狀就好了,可是,這題恰恰要求了時間複雜讀:O(n),難啊,抓頭髮,拼命抓,當然,既然是題目,自然會有解法,還是兩個for迴圈,不過不是兩層,第一個for迴圈,計算前i個數的積,並存入output陣列相應位置,第二個for迴圈,倒序遍歷,以題目給的示例為例,返回列表output

最後一個元素就是原始列表前三個數的積,倒數第二個元素就是原始列表前兩個數的積最後一位的積,倒數第三個元素就是原始列表前一個數的積最後兩位的積,第一個元素就是原始列表最後三位的積,具體思路如下圖所述:
這可能是是目前為止除了Manacher‘s Algorithm最複雜的思路了

四、解題

1.快捷的方法:

時間複雜度:O(n)
空間複雜度上,根據題意不考慮輸出列表,下列程式碼的空間複雜度為:O(1)
(1)程式碼

class Solution(object):
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
p = 1 # 原始資料下標 n = len(nums) # 原始列表長度 output = [] # 返回列表 for i in range(0,n): # 第一個for迴圈,實現求前n位數的乘積 # 並把結果儲存在output列表 output.append(p) p = p * nums[i] p = 1 # 回到最原始資料下標 for i in range(n-1,-1,-1): # 第二個for迴圈,倒序遍歷,實現題目要求 # 並把結果儲存在output列表 output[i] = output[i] * p p = p * nums[i] # 求後n-i位的積 return output

(2)提交結果
提交結果

測試資料:17組
執行時間:124ms
擊敗人百分比:59.68%

思想很巧妙,理解很困難。

2.給大家介紹一種比較炸天的方法

兩行程式碼解決,這裡呼叫了reduce函式,這樣算看上去時間複雜度也是O(n),只看到一個for迴圈,但實際上reduce函式內部也是遍歷實現功能,所以時間複雜度為O(n^2)
(1)程式碼

class Solution1:
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        from functools import reduce
        return [ reduce(lambda x,y:x*y,nums[:i]+nums[i+1:]) for i in range(len(nums))]

(2)思路介紹
程式碼介紹
(3)提交結果
時間超出限制
(4)科補小知識
reduce函式
reduce() 函式會對引數序列中元素進行累積。
函式將一個數據集合(連結串列,元組等)中的所有資料進行下列操作:用傳給 reduce 中的函式 function(有兩個引數)先對集合中的第 1、2 個元素進行操作,得到的結果再與第三個資料用 function 函式運算,最後得到一個結果。

reduce(function, iterable[, initializer])

function -- 函式,有兩個引數
iterable -- 可迭代物件
initializer -- 可選,初始引數

簡單點說,reduce可以遍歷傳入的iterable,進行function的具體操作,這樣簡短精悍,充分體現了Python的優雅性。

lambda函式
lambda表示式,通常是在需要一個函式,但是又不想費神去命名一個函式的場合下使用,也就是指匿名函式,適用於功能比較簡單的函式,如果函式功能很複雜,就直接寫一個函式即可,不然強行改成lambda表示式不易理解,反而失去了程式的可讀性。

雖然beat的人不多,但我有想法,我驕傲啊~
感覺很酷,感覺很努力,現實很殘酷,有沒有這種感覺?

五、疑惑

思想很複雜,實現很有趣,只要不放棄,終有成名日。
—《老表打油詩》

六、結語

加我微信:zs820553471,備註:leetcode,加入專門的leetcode刷題交流群。
堅持 and 努力 : 終有所獲。

歡迎大家關注微信公眾號:極簡XksA,獲取Python/Java/前端等學習資源!

極簡XksA