题目:

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. NPOI操作EXCEL 类代码

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using NPOI.SS. ...

  2. 禁用浏览器缓存Ajax请求

    $.ajax({ url: 'url.php', cache: false, success: function(data){ //..... } }); 仅Get有缓存, Post不会缓存

  3. IOS-用动画组制作花瓣掉落效果(另附iOS动画图表)

    重要的两个方法:1.动画的数组:animations 2.启动的时间 beginTime 注意:动画组设置了持续时间(duration)可能会导致动画组里面的持续时间不管用 代码如下: #import ...

  4. 电脑中java环境的搭建

  5. 手把手教你写电商爬虫-第三课 实战尚妆网AJAX请求处理和内容提取

    版权声明:本文为博主原创文章,未经博主允许不得转载. 系列教程: 手把手教你写电商爬虫-第一课 找个软柿子捏捏 手把手教你写电商爬虫-第二课 实战尚妆网分页商品采集爬虫 看完两篇,相信大家已经从开始的 ...

  6. [leetcode] 401. Binary Watch

    https://leetcode.com/contest/5/problems/binary-watch/ 这个题应该是这次最水的,这个题目就是二进制,然后是10位,最大1024,然后遍历,找二进制里 ...

  7. Linux下UDP收/发广播消息简单实现

    发送广播消息 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/typ ...

  8. 转载 shell sort

    http://blog.sina.com.cn/s/blog_6d09b5750100x6zg.html 首先是shell排序实现多列排序,这里添加竖线以作分割,如下文件test: a|gggg|4| ...

  9. #Leet Code# Permutation

    描述: 输出全排列 代码: class Solution: # @param num, a list of integer # @return a list of lists of integers ...

  10. Python多线程启动http.server

    OS: Windows 8.1 with update 关键字:Python3.4, http.server, Thread 例子代码如下: import os from threading impo ...