题目:

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的处理。

  1. 这里我们对这道题目,先创建一个global max = Integer.MIN_VALUE,一个保存当前正数最大值的posMax = 1和一个保存当前负数最小值的negMax = 1。
  2. 接下来我们开始从0遍历数组。主要考虑三种情况, 当前num 大于,小于,等于 0。
    1. 当num > 0的时候,我们直接将posMax和negMax与 num相乘,然后尝试更新max
    2. 当num < 0的时候,我们先设置一个tmp = posMax。
      1. 在当前negMax < 0的时候
        1. 我们可以更新posMax = negMax * max, 负负得正
        2. 更新negMax = tmp * num, 即negMax为之前的posMax * num
        3. 尝试更新max = Math.max(max, posMax)
      2. 否则negMax > 0
        1. 因为num是负数,所有我们更新posMax = 1
        2. 更新negMax *= num
        3. 尝试更新 max = Math.max(max, num), 即max跟当前数字进行比较
    3. 当num == 0的时候,这时候之前cache的乘积都断了

      1. 我们更新posMax = 1,  negMax = 1
      2. 尝试更新 max = Math.max(max, num)。  即max跟当前数字比较, 因为当前数字num = 0,所以也可以直接写 Math.max(max, 0)。
  3. 返回结果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的更多相关文章

  1. leetcode 53. Maximum Subarray 、152. Maximum Product Subarray

    53. Maximum Subarray 之前的值小于0就不加了.dp[i]表示以i结尾当前的最大和,所以需要用一个变量保存最大值. 动态规划的方法: class Solution { public: ...

  2. 152. Maximum Product Subarray - LeetCode

    Question 152. Maximum Product Subarray Solution 题目大意:求数列中连续子序列的最大连乘积 思路:动态规划实现,现在动态规划理解的还不透,照着公式往上套的 ...

  3. 求连续最大子序列积 - leetcode. 152 Maximum Product Subarray

    题目链接:Maximum Product Subarray solutions同步在github 题目很简单,给一个数组,求一个连续的子数组,使得数组元素之积最大.这是求连续最大子序列和的加强版,我们 ...

  4. 【刷题-LeetCode】152 Maximum Product Subarray

    Maximum Product Subarray Given an integer array nums, find the contiguous subarray within an array ( ...

  5. [LeetCode] 152. Maximum Product Subarray 求最大子数组乘积

    Given an integer array nums, find the contiguous subarray within an array (containing at least one n ...

  6. [LeetCode]152. Maximum Product Subarray

    This a task that asks u to compute the maximum product from a continue subarray. However, you need t ...

  7. LeetCode 152. Maximum Product Subarray (最大乘积子数组)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  8. 152. Maximum Product Subarray (Array; DP)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  9. Java for LeetCode 152 Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  10. leetcode 152. Maximum Product Subarray --------- java

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

随机推荐

  1. Exam 70-462 Administering Microsoft SQL Server 2012 Databases 复习帖

    好吧最近堕落没怎么看书,估计这个月前是考不过了,还是拖到国庆之后考试吧.想着自己复习考试顺便也写点自己的复习的概要,这样一方面的给不准备背题库的童鞋有简便的复习方法(好吧不被题库的同学和我一样看MSD ...

  2. 学习笔记1_Day09_Servlet

    生命周期方法: l  void init(ServletConfig):出生之后(1次): l  void service(ServletRequest request, ServletRespons ...

  3. Java实战之02Hibernate-02映射、一级缓存、实体对象状态

    五.映射基础 1.实体类采用javabean的编写规范 JavaBean编写规范: a.类一般是public的 b.有默认的构造方法 c.字段都是私有的 d.提供公有的getter和setter方法 ...

  4. extern int a[] VS extern int *a

    array VS pointer 参考: 1.Extern using pointer instead of array array is not pointer 2.extern array que ...

  5. OpenJudge/Poj 1163 The Triangle

    1.链接地址: http://bailian.openjudge.cn/practice/1163 http://poj.org/problem?id=1163 2.题目: 总时间限制: 1000ms ...

  6. PHP页面间参数传递的四种方法详解

    2016-04-16 定义page01.php和page02.php两个php文件,将page01中的内容想办法传递到page02,然后供我们继续使用.------------------------ ...

  7. 用LinqToExcel处理有标题表格的数据

    1. 先根据表格标题定义一个类. public class News { public string Title { set; get; } public string Content { set; ...

  8. position:absolute,绝对定位和相对定位,JQ隐藏和显示

    需要在指定位置,用绝对定位. 如果直接写position:absolute,top:0;left:0,那就是以浏览器的左上角为参照了 现在需要在某一个指定位置用绝对定位 解决方法 在需要用绝对定位(p ...

  9. 如何使用ERStudio 生成comment

    在ER使用中,在生成sql过程中,如何批量生成字段描述,如何批量添加Owner,请看下文: 1.ER生成字段描述 2.ER生成描述添加Owner 使用的ER版本是8.0,英文版本,在操作过程中,有些配 ...

  10. php 导出excel表格

    方式一:使用PHPExcel类库 //引入PHPExcel库文件(路径根据自己情况)include './phpexcel/Classes/PHPExcel.php'; $excel = new PH ...