LeetCode-152. 乘積最大子陣列
阿新 • • 發佈:2021-12-23
題目來源
題目詳情
給你一個整數陣列 nums
,請你找出陣列中乘積最大的連續子陣列(該子陣列中至少包含一個數字),並返回該子陣列所對應的乘積。
示例 1:
輸入: [2,3,-2,4]
輸出: 6
解釋:子陣列 [2,3] 有最大乘積 6。
示例 2:
輸入: [-2,0,-1]
輸出: 0
解釋:結果不能為 2, 因為 [-2,-1] 不是子陣列。
題解分析
解法一-動態規劃
- 這題其實是最大連續子陣列題目的變型,原來的題目是求解連續子陣列的最大和。但遺憾的是,這題和原來的題目還是有很大區別的。因為乘積時可能遇到負數,但是負數和負數相乘會導致正數的出現,這是加法和減法所沒有的特徵。
- 因此,也不能使用類似於最大連續子陣列和的狀態轉移方程(\(dp[i] = max(dp[i-1] + nums[i], nums[i]\),最大值為dp結果陣列中各元素的最大值),需要採用新的思路來求解乘積子陣列的最大值。
- 考慮到這裡有負數會影響狀態轉移,並且如果當前數為負數,則我們希望該數前面的乘積為負數,且越小越好;如果當前數為正數,則我們希望前面數的乘積為正,且越大越好。
- 我們可以定義兩個dp陣列,一個儲存最大乘積,一個儲存最小乘積,結果為最大乘積陣列各元素中的最大值。
Either Excellent or Rustyclass Solution { final int MINS = -0X3F3F3F3F; public int maxProduct(int[] nums) { if(nums == null || nums.length == 0){ return 0; } int len = nums.length; int[] dpmax = Arrays.copyOf(nums, len); int[] dpmin = Arrays.copyOf(nums, len); for(int i=1; i<len; i++){ dpmax[i] = Math.max(dpmax[i-1] * nums[i], Math.max(dpmin[i-1] * nums[i], nums[i])); dpmin[i] = Math.min(dpmax[i-1] * nums[i], Math.min(dpmin[i-1] * nums[i], nums[i])); } int maxs = MINS; for(int i=0; i<len; i++){ maxs = Math.max(maxs, dpmax[i]); } return maxs; } }