一、前言
讓人成長的不是歲月,而是經歷。
每天五分鐘,看懂一道簡單、中等難度的算法題,儘可能將複雜的題講清楚。
瘋狂學習python中,2020-06-02更新
二、題目
給你一個長度爲 n 的整數數組 nums,其中 n > 1,返回輸出數組 output ,其中 output[i] 等於 nums 中除 nums[i] 之外其餘各元素的乘積。
示例:
輸入: [1,2,3,4]
輸出: [24,12,8,6]
**提示:**題目數據保證數組之中任意元素的全部前綴元素和後綴(甚至是整個數組)的乘積都在 32 位整數範圍內。
說明: 請不要使用除法,且在 O(n) 時間複雜度內完成此題。
進階:
你可以在常數空間複雜度內完成這個題目嗎?( 出於對空間複雜度分析的目的,輸出數組不被視爲額外空間。)
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/product-of-array-except-self
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
三、解題思路
3.1 步驟解釋
輸入: [1,2,3,4]
輸出: [24,12,8,6]
24 = 1 * 2 * 3 * 4
12= 1 * 2 * 3 * 4
8= 1 * 2 * 3 * 4
6= 1 * 2 * 3 * 4
如果拋開不能使用除法這個限制條件,那麼這個題是一個簡單題,通過列表求乘積,然後除以自身的值即可。
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
l = []
for i in nums:
l.append(reduce(lambda x, y: x*y, nums)/i)
print(l)
但是如果列表中有爲0的元素,則會報錯。
3.1 左右乘積法
思路:
- 遍歷記錄每個位置之前前綴的乘積和每個位置之後後綴的乘積。
- 遍歷記錄每個位置前綴乘積乘以後綴乘積返回。
對於進階所提到的在常數空間複雜度內完成題目,可以直接將答案存儲在輸出數組中。即首先循環數組,得到圖中的leftProduct數組,只不過此時是使用res數組來存的。
接下來簡單化簡一下計算流程:
res[i] = L[i] * R[i]
由於:L[i]此時存儲在res[i]中的
因此:res[i] = res[i] * R[i]
由於:R[i] = nums[i + 1] * R[i + 1]
因此:res[i] = res[i] = (nums[i + 1] R[i + 1])**
參考來源:圖解LeetCode238. 除自身以外數組的乘積
四、代碼實例
4.1 左右乘積法
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
length = len(nums)
res = [1] * length # 初始化長度爲 le(nums) 的數組
R, L = 1, 1 # 左右的乘積
# 右邊的乘積
for i in (reversed(range(length))):
R *= nums[i]
res[i] = R
# 左邊乘積*右邊的乘積
for i in range(length - 1):
res[i] = res[i + 1] * L
L *= nums[i]
res[-1] = L
return res