leetcode152. 乘積最大子序列

給定一個整數數組 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 }
View Code
相關文章
相關標籤/搜索