31.動態規劃-乘積最大子序列-Leetcode 152(python)
阿新 • • 發佈:2018-12-05
- 題目描述
給定一個整數陣列 nums
,找出一個序列中乘積最大的連續子序列(該序列至少包含一個數)。
- 示例
示例 1:
輸入: [2,3,-2,4]
輸出: 6
解釋: 子陣列 [2,3] 有最大乘積 6。
示例 2:
輸入: [-2,0,-1] 輸出: 0 解釋: 結果不能為 2, 因為 [-2,-1] 不是子陣列。
- 自己的錯誤思路
自以為抄了足夠多的動態規劃的題了,怎麼著也應該對這種思想有一點理解,沒想到還是有坑,我的想法就是用dp陣列記錄到當前元素為止的子串中,能夠得到的最大乘積,自以為考慮非常周到,因為還想到了要判斷dp[i-1]<0/=0/>0和nums[i]<0/>0/=0的情況。
但是按照我的思路來做的話,如果輸入是[-2,3,-4],輸出就是3。很顯然這樣是錯的,因為我的做法是記錄最大值,那麼dp[1]就是3,但是接下來的nums[2]是-4,是個負數,如果它和dp[1]可以取的另一個值也就是-6相乘的話,很明顯能夠得到比3大的多的乘積,也就是24,然而按我的只記錄最大乘積的做法,就會認為dp[2] = 3
- 正確的解決思路
一個比較完整健全的解決思路(來自網友):
在第i個元素時,我們能夠取到的子序列的最大乘積可能來自:
(1)nums[i]本身
(2)nums[i-1]能夠取到的最大子序列的乘積
(3)包含nums[i-1]的最大連乘值 * nums[i] (兩個部分均為正數)
(4)包含nums[i-1]的最小連乘值 * nums[i] (兩個部分均為負數)
因此對於第i個元素,我們需要記錄的值有三個:
(1)能夠取到的子序列的最大乘積
(2)包含當前位置的最大連乘值
(3)包含當前位置的最小連乘值
- 程式碼
class Solution(object): def maxProduct(self, nums): """ :type nums: List[int] :rtype: int """ #temp記錄整個陣列的子序列最大連乘積 temp = nums[0] length = len(nums) #M陣列記錄包含當前位置的最大連乘值 M = [0 for i in range(length)] #m陣列記錄包含當前位置的最小連乘值 m = [0 for i in range(length)] for i in range(length): if i == 0: M[i] = nums[i] m[i] = nums[i] else: #包含當前位置的最大連乘值從:當前位置和到第i-1個元素的最大連乘值的乘積、當前元素中選出 M[i] = max(max(M[i-1]*nums[i],m[i-1]*nums[i]),nums[i]) m[i] = min(min(M[i-1]*nums[i],m[i-1]*nums[i]),nums[i]) temp = max(temp,M[i]) return temp