給定一個整數數組 nums ,找出一個序列中乘積最大的連續子序列(該序列至少包含一個數)。
示例 1:
輸入: [2,3,-2,4]
輸出: 6
解釋: 子數組 [2,3] 有最大乘積 6。
示例 2:
輸入: [-2,0,-1]
輸出: 0
解釋: 結果不能爲 2, 由於 [-2,-1] 不是子數組。
來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/maximum-product-subarray
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。數組
解答:網絡
1.一開始的想法是利用一個數組dp,保存最大值,可是數組中有負數,因此沒法判斷以前的負數可能碰見這個元素就變成最大值了。ide
2.而後想的是能不能簡化暴力法,想到用一個二維dp數組,將nums數組的子序列乘積值保存一下,而後計算後面的值既能夠用前面的值了,好比說spa
1~5,能夠是1~4*nums[5],這樣不須要從新計算一遍,可是數組空間爆了,倒數第二個案例經過不了。。。。因此這種解法nocode
3.看解析了,發現別人是在1的基礎上再添加一個mindp數組,其實表明一種想法就是,每次遇到的元素就是正數或者負數,而後前面的值多是正數,負數,因此咱們用mindp保存可能遇到的負數最小值,可是max中保存的是最大值,因此只須要拿前一個的最小值,最大值分別乘以nums[i],而後還須要跟nums[i]本身比較誰最大,畢竟,可能這個子序列走到i的時候前面都不理想,那麼從i開始不是也是一種子序列的選擇嗎?blog
dpmax[i]=max(nums[i],nums[i]*dpmin[i-1],nums[i]*dpmax[i-1]),從三者間取出一個最大值,那麼一樣的,min就是取出最小值。leetcode
1 class Solution { 2 public int maxProduct(int[] nums) { 3 int n=nums.length; 4 int[] dpMax=new int[n]; 5 int[] dpMin=new int[n]; 6 dpMax[0]=dpMin[0]=nums[0]; 7 for(int i=1;i<n;i++) 8 { 9 dpMax[i]=Math.max(dpMax[i-1]*nums[i],Math.max(nums[i],dpMin[i-1]*nums[i])); 10 dpMin[i]=Math.min(dpMax[i-1]*nums[i],Math.min(nums[i],dpMin[i-1]*nums[i])); 11 } 12 int max=dpMax[0]; 13 for(int i=1;i<n;i++) 14 max=Math.max(max,dpMax[i]); 15 return max; 16 } 17 }