作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/maximum-product-subarray/description/

题目描述

Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.

Example 1:

Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.

Example 2:

Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.

题目大意

求连续子数组最大乘积。

解题方法

双重循环

这个题最简单粗暴的方法当然是两重循环啦!遍历每个区间的开始和结束位置,然后求这个区间的积,然后保留最大的积即可。没想到C++直接提交竟然给通过了!说明这个O(N^2)的时间复杂度还是能够接受的。

class Solution {
public:
int maxProduct(vector<int>& nums) {
const int N = nums.size();
int res = INT_MIN;
for (int i = 0; i < N; ++i) {
int cur = 1;
for (int j = i; j < N; ++j) {
if (j == i)
cur = nums[i];
else
cur = cur * nums[j];
res = max(res, cur);
}
}
return res;
}
};

动态规划

如果是连续子数组的和的问题我们肯定能想到虫取法之类的,但是求积就比较麻烦了,因为某个位置可能出现了0或者负数。。当遇到0的时候,整个乘积会变成0;当遇到负数的时候,当前的最大乘积会变成最小乘积,最小乘积会变成最大乘积。

有上面的分析可以看出,必须使用两个数组分别记录以某个位置i结尾的时候的最大乘积和最小乘积了。令最大乘积为f,最小乘积为g。那么有:

  • 当前的最大值等于已知的最大值、最小值和当前值的乘积,当前值,这三个数的最大值。
  • 当前的最小值等于已知的最大值、最小值和当前值的乘积,当前值,这三个数的最小值。
  • 结果是最大值数组中的最大值。

时间复杂度是O(N),空间复杂度是O(N). N是数组大小。超过了87%的提交。

题外话:是不是和股票交易问题很像?

class Solution(object):
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums: return 0
N = len(nums)
f = [0] * N
g = [0] * N
f[0] = g[0] = res = nums[0]
for i in range(1, N):
f[i] = max(f[i - 1] * nums[i], nums[i], g[i - 1] * nums[i])
g[i] = min(f[i - 1] * nums[i], nums[i], g[i - 1] * nums[i])
res = max(res, f[i])
return res

这个版本的C++代码如下:

class Solution {
public:
int maxProduct(vector<int>& nums) {
const int N = nums.size();
vector<int> mx(N);
vector<int> mn(N);
int res = mx[0] = mn[0] = nums[0];
for (int i = 1; i < N; ++i) {
mx[i] = max(nums[i], max(mx[i - 1] * nums[i], mn[i - 1] * nums[i]));
mn[i] = min(nums[i], min(mx[i - 1] * nums[i], mn[i - 1] * nums[i]));
res = max(mx[i], res);
}
return res;
}
};

上面的方法使用了数组实现,我们注意到,每次更新只用到了前面的一个值,所以可以使用变量优化空间复杂度。

class Solution(object):
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums: return 0
N = len(nums)
f = g = res = nums[0]
for i in range(1, N):
pre_f, pre_g = f, g
f = max(pre_f * nums[i], nums[i], pre_g * nums[i])
g = min(pre_f * nums[i], nums[i], pre_g * nums[i])
res = max(res, f)
return res

时间复杂度是O(N),空间复杂度是O(1).N是数组大小。超过了99.9%的提交。

在上面两个做法中,使用求三个数最大、最小的方式来更新状态,确实很暴力。事实上可以使用判断,直接知道怎么优化。当nums[i]为正的时候,那么正常更新。如果nums[i]<=0的时候,需要反向更新。

class Solution(object):
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums: return 0
N = len(nums)
f = g = res = nums[0]
for i in range(1, N):
if nums[i] > 0:
f, g = max(f * nums[i], nums[i]), min(g * nums[i], nums[i])
else:
f, g = max(g * nums[i], nums[i]), min(f * nums[i], nums[i])
res = max(res, f)
return res

时间复杂度是O(N),空间复杂度是O(1).N是数组大小。超过了47%的提交。

在上面的做法中可以看出来,两个更新公式里面f和g的位置是互换的,所以可以提前判断nums[i]的正负进行提前的互换。

class Solution(object):
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums: return 0
N = len(nums)
f = g = res = nums[0]
for i in range(1, N):
if nums[i] < 0:
f, g = g, f
f, g = max(f * nums[i], nums[i]), min(g * nums[i], nums[i])
res = max(res, f)
return res

时间复杂度是O(N),空间复杂度是O(1).N是数组大小。超过了47%的提交。

参考资料

http://www.cnblogs.com/grandyang/p/4028713.html

日期

2018 年 10 月 20 日 —— 10月剩余的时间又不多了

【LeetCode】152. Maximum Product Subarray 解题报告(Python & C++)的更多相关文章

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

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

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

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

  3. Java for LeetCode 152 Maximum Product Subarray

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

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

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

  5. LeetCode Maximum Product Subarray 解题报告

    LeetCode 新题又更新了.求:最大子数组乘积. https://oj.leetcode.com/problems/maximum-product-subarray/ 题目分析:求一个数组,连续子 ...

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

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

  7. C#解leetcode 152. Maximum Product Subarray

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

  8. [leetcode]152. Maximum Product Subarray最大乘积子数组

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

  9. Leetcode#152 Maximum Product Subarray

    原题地址 简单动态规划,跟最大子串和类似. 一维状态空间可以经过压缩变成常数空间. 代码: int maxProduct(int A[], int n) { ) ; ]; ]; ]; ; i > ...

随机推荐

  1. 在R语言中使用Stringr进行字符串操作

    今天来学习下R中字符串处理操作,主要是stringr包中的字符串处理函数的用法. 先导入stringr包,library(stringr),require(stringr),或者stringr::函数 ...

  2. Linux-设置终端界面的字体颜色和自定义常用快捷功能

    .bashrc是一个隐藏的文件,要打开并修改该文件需要: (0)命令:cd ~ (1)命令:ls -a 找到文件 .bashrc: (2) 命令 vim ~/.bashrc 进入到文件: (3) 直接 ...

  3. 框架学习-MyBatis(01)

    1.MyBatis是持久层框架 什么是持久化: 狭义:把数据永久性的保存到数据当中 广义:针对于数据库的所有操作都称为持久化操作,CreateReadUpdateDelete操作 2.有哪些持久层框架 ...

  4. MybatisPlus入门程序

    参考资料:MybatisPlus官网 环境搭建 创建数据库 CREATE DATABASE `mybatisplus` ​ USE `mybatisplus` ​ CREATE TABLE `user ...

  5. centos7 自动同步时间

    rm -rf /etc/localtime ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime vim /etc/sysconfig/cloc ...

  6. OS开发之Objective-C与JavaScript的交互

    UIWebView是iOS最常用的SDK之一,它有一个stringByEvaluatingJavaScriptFromString方法可以将javascript嵌入页面中,通过这个方法我们可以在iOS ...

  7. Centos 7 安装redis,修改配置文件不生效、外网不能访问。

    前提: 在用Centos 7 安装 redis 时,遇上一下几个问题 ,记录下 . 1.修改配置文件,按官网步骤启动,不生效. 2.外网无法访问redis. 步骤: 1.打开centos 虚拟机 ,按 ...

  8. ExecutorService 线程池详解

    1.什么是ExecutorService,为什么要使用线程池? 许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务,每当一个请求到达就创建一个新线程,然后在新线程中为请求服务,但是频繁创建新 ...

  9. 通过静态分析和持续集成 保证代码的质量 (Helix QAC)1

    前言 现代软件开发团队面临着很多挑战,这些挑战包括:产品交付期限越来越紧,团队的分布越来越广,软件的复杂度越来越高,而且对软件的质量要求越来越高. 本文分为两个章节.第一章讨论持续集成的原理,持续集成 ...

  10. 【JavaWeb】【JSP】JSP传值到Servlet后端为NULL的问题

    JSP传值到Servlet后端为NULL的问题 哔哩哔哩@萌狼蓝天 博客:萌狼工作室-博客园 联系QQ:#3447902411# | 仅限技术交流可添加 | 添加请说明你的方向和来意 1.目标文件路径 ...