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
相关文章
相关标签/搜索