152. Maximum Product Subarray
题目:
Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4]
,
the contiguous subarray [2,3]
has the largest product = 6
.
链接: http://leetcode.com/problems/maximum-product-subarray/
题解:
求最大乘积子数组。 依然是用Dynamic Programming的思想,不过这回我们要维护一个max以及一个min。根据nums[i]的符号来决定应该怎样计算就可以了。
Time Complexity - O(n), Space Complexity - O(1)。
public class Solution {
public int maxProduct(int[] nums) {
if(nums == null || nums.length == 0)
return 0;
int res = nums[0], max = nums[0], min = nums[0]; for(int i = 1; i < nums.length; i++) {
if(nums[i] > 0) {
max = Math.max(nums[i], nums[i] * max);
min = Math.min(nums[i], nums[i] * min);
} else {
int max_copy = max;
max = Math.max(nums[i], nums[i] * min);
min = Math.min(nums[i], nums[i] * max_copy);
}
res = Math.max(res,max);
} return res;
}
}
二刷:
一刷肯定没好好做,直接拷贝答案了吧....导致如今没什么大印象。
下面代码写得比较糙,没有加上overflow和underflow的处理。
- 这里我们对这道题目,先创建一个global max = Integer.MIN_VALUE,一个保存当前正数最大值的posMax = 1和一个保存当前负数最小值的negMax = 1。
- 接下来我们开始从0遍历数组。主要考虑三种情况, 当前num 大于,小于,等于 0。
- 当num > 0的时候,我们直接将posMax和negMax与 num相乘,然后尝试更新max
- 当num < 0的时候,我们先设置一个tmp = posMax。
- 在当前negMax < 0的时候
- 我们可以更新posMax = negMax * max, 负负得正
- 更新negMax = tmp * num, 即negMax为之前的posMax * num
- 尝试更新max = Math.max(max, posMax)
- 否则negMax > 0
- 因为num是负数,所有我们更新posMax = 1
- 更新negMax *= num
- 尝试更新 max = Math.max(max, num), 即max跟当前数字进行比较
- 在当前negMax < 0的时候
- 我们更新posMax = 1, negMax = 1
- 尝试更新 max = Math.max(max, num)。 即max跟当前数字比较, 因为当前数字num = 0,所以也可以直接写 Math.max(max, 0)。
当num == 0的时候,这时候之前cache的乘积都断了
- 返回结果max。
写得比较繁杂,应该可以简化不少。留给下一次了。 参观了一下Discuss区,大神们写得好棒好巧妙...收录在reference里。 下回再写的时候要参考写出简单的代码。
Java:
public class Solution {
public int maxProduct(int[] nums) {
if (nums == null || nums.length == 0) return 0;
int max = Integer.MIN_VALUE;
int posMax = 1, negMax = 1;
for (int num : nums) {
if (num > 0) {
posMax *= num;
negMax *= num;
max = Math.max(max, posMax);
} else if (num < 0) {
if (negMax < 0) {
int tmp = posMax;
posMax = negMax * num;
negMax = tmp * num;
max = Math.max(max, posMax);
} else {
posMax = 1;
negMax *= num;
max = Math.max(max, num);
}
} else {
posMax = 1;
negMax = 1;
max = Math.max(max, num);
}
}
return max;
}
}
来自mzchen大神的swap做法,好巧妙:
这里我们跟上面一样维护一个min和一个max,以及一个global的结果res。每次当nums[i] < 0的时候,我们swap一下min和max。在一般情况下,我们更新
max = Math.max(nums[i], max * nums[i]), min = Math.min(nums[i], min * nums[i]),这两个步骤可以处理nums[i] = 0的case。最后我们尝试更新res = Math.max(res, max)。
Java:
public class Solution {
public int maxProduct(int[] nums) {
if (nums == null || nums.length == 0) return 0;
int res = nums[0];
int max = nums[0], min = nums[0];
for (int i = 1; i < nums.length; i++) {
if (nums[i] < 0) {
int tmp = max;
max = min;
min = tmp;
}
max = Math.max(nums[i], max * nums[i]);
min = Math.min(nums[i], min * nums[i]);
res = Math.max(res, max);
}
return res;
}
}
Update:
public class Solution {
public int maxProduct(int[] nums) {
if (nums == null || nums.length == 0) return 0;
int max = 1, min = 1;
int res = Integer.MIN_VALUE;
for (int num : nums) {
if (num < 0) {
int tmp = max;
max = min;
min = tmp;
}
max = Math.max(num, max * num);
min = Math.min(num, min * num);
res = Math.max(res, max);
}
return res;
}
}
Test cases:
[-5, 2, -1, -7]
[-1, 2, 3, -4]
[-5, 2, 0, -1, -7]
[-1, -2, -3, -4]
[0, -5, -2, -1, 7]
[-2]
[2]
[-2, -2, -2, -2]
[Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE] <- 这个没有测
Reference:
https://leetcode.com/discuss/11923/sharing-my-solution-o-1-space-o-n-running-time
https://leetcode.com/discuss/14235/possibly-simplest-solution-with-o-n-time-complexity
https://leetcode.com/discuss/19795/share-my-c-solution-maybe-is-the-simplest-solution
https://leetcode.com/discuss/16238/simple-java-code
https://leetcode.com/discuss/64079/my-concise-dp-o-n-java-solution-with-o-1-extra-space
152. Maximum Product Subarray的更多相关文章
- leetcode 53. Maximum Subarray 、152. Maximum Product Subarray
53. Maximum Subarray 之前的值小于0就不加了.dp[i]表示以i结尾当前的最大和,所以需要用一个变量保存最大值. 动态规划的方法: class Solution { public: ...
- 152. Maximum Product Subarray - LeetCode
Question 152. Maximum Product Subarray Solution 题目大意:求数列中连续子序列的最大连乘积 思路:动态规划实现,现在动态规划理解的还不透,照着公式往上套的 ...
- 求连续最大子序列积 - leetcode. 152 Maximum Product Subarray
题目链接:Maximum Product Subarray solutions同步在github 题目很简单,给一个数组,求一个连续的子数组,使得数组元素之积最大.这是求连续最大子序列和的加强版,我们 ...
- 【刷题-LeetCode】152 Maximum Product Subarray
Maximum Product Subarray Given an integer array nums, find the contiguous subarray within an array ( ...
- [LeetCode] 152. Maximum Product Subarray 求最大子数组乘积
Given an integer array nums, find the contiguous subarray within an array (containing at least one n ...
- [LeetCode]152. Maximum Product Subarray
This a task that asks u to compute the maximum product from a continue subarray. However, you need t ...
- LeetCode 152. Maximum Product Subarray (最大乘积子数组)
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- 152. Maximum Product Subarray (Array; DP)
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- Java for LeetCode 152 Maximum Product Subarray
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- leetcode 152. Maximum Product Subarray --------- java
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
随机推荐
- VS2015+AngularJS+Ionic开发
安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...
- 【转】JavaScript系列文章:自动类型转换
我们都知道,JavaScript是类型松散型语言,在声明一个变量时,我们是无法明确声明其类型的,变量的类型是根据其实际值来决定的,而且在运行期间,我们可以随时改变这个变量的值和类型,另外,变量在运行期 ...
- 项目开发中常用到的SQL语句
阅读目录 循环示例 循环示例 循环示例 循环示例 1.循环示例 在前端面试中最常见的问题就是页面优化和缓存(貌似也是页面优化),被问了几次后心虚的不行,平然平时多少会用到一些,但突然问我,很难把自己知 ...
- CPrintDialog
CPrintDialog 封装windows为打印提供服务的通用窗体. BOOL GetDefaults(); //获取默认设备,不显示对话框 // Helpers for parsing infor ...
- WCF与Web API 区别(应用场景)
Web api 主要功能: 支持基于Http verb (GET, POST, PUT, DELETE)的CRUD (create, retrieve, update, delete)操作 请求的回 ...
- FlashBuilder启动时一闪而过
晚上的时候把项目目录直接剪切走了 早晨就打不开了 去workspace看log .\workspace\.metadata\.log 发现如下代码!MESSAGE Could not read me ...
- mongodb 数据备份,还原笔记
公司数据库迁移,所以补充了一下知识: 1 集合的导入和导出 命令行帮助 mongoexport --help 导出 导出 newsServer 数据库下 news 集合 mongoexport - ...
- IO流06_处理流
[处理流] 处理流可以隐藏底层设备上节点流的差异,并对外提供更加方便的输入/输出的方法. 使用处理流的思路: 使用处理流来包装节点流,程序通过处理流来执行输入输出功能,让节点流与底层的I/O设备.文件 ...
- HDU 4430 Yukari's Birthday(二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4430 题目大意:给定n个蜡烛,围绕蛋糕的中心插同心圆,从里往外分别是第1圈.第2圈....第r圈,第 ...
- win2008 r2 远程桌面问题
今天去机房给三台服务器上架,装了2008 R2系统,客户要求从外面通过公网IP能够访问服务器桌面,三台服务器都安装了远程协助的功能,结果有两台能正常访问,另外一台始终连不上,不知道哪个地方设置有问题, ...