【LeetCode】152. Maximum Product Subarray 解题报告(Python & C++)
作者: 负雪明烛
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++)的更多相关文章
- 求连续最大子序列积 - leetcode. 152 Maximum Product Subarray
题目链接:Maximum Product Subarray solutions同步在github 题目很简单,给一个数组,求一个连续的子数组,使得数组元素之积最大.这是求连续最大子序列和的加强版,我们 ...
- [LeetCode] 152. Maximum Product Subarray 求最大子数组乘积
Given an integer array nums, find the contiguous subarray within an array (containing at least one n ...
- 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 (最大乘积子数组)
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- LeetCode Maximum Product Subarray 解题报告
LeetCode 新题又更新了.求:最大子数组乘积. https://oj.leetcode.com/problems/maximum-product-subarray/ 题目分析:求一个数组,连续子 ...
- leetcode 152. Maximum Product Subarray --------- java
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- C#解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最大乘积子数组
Given an integer array nums, find the contiguous subarray within an array (containing at least one n ...
- Leetcode#152 Maximum Product Subarray
原题地址 简单动态规划,跟最大子串和类似. 一维状态空间可以经过压缩变成常数空间. 代码: int maxProduct(int A[], int n) { ) ; ]; ]; ]; ; i > ...
随机推荐
- excel-合并多个Excel文件--VBA合并当前目录下所有Excel工作簿中的所有工作表
在网上找EXCEL多文件合并的方法,思路: 一.Linux 或者window+cmder,直接用命令行cat合并EXCEL文件,但是,需要安装辅助东西才能直接处理(也许也不可以,但是,可以用文件格式转 ...
- SpringCloud微服务实战——搭建企业级开发框架(二十八):扩展MybatisPlus插件DataPermissionInterceptor实现数据权限控制
一套完整的系统权限需要支持功能权限和数据权限,前面介绍了系统通过RBAC的权限模型来实现功能的权限控制,这里我们来介绍,通过扩展Mybatis-Plus的插件DataPermissionInterce ...
- 33、搜索旋转排序数组 | 算法(leetode,附思维导图 + 全部解法)300题
零 标题:算法(leetode,附思维导图 + 全部解法)300题之(33)搜索旋转排序数组 一 题目描述! 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: // 方案1 & ...
- Kubernetes:应用自动扩容、收缩与稳定更新
在前面我们已经学习到了 Pod 的扩容.滚动更新等知识,我们可以手动为 Deployment 等设置 Pod 副本的数量,而这里会继续学习 关于 Pod 扩容.收缩 的规则,让 Pod 根据节点服务器 ...
- javaSE高级篇1 — 异常与多线程基础
1.异常的体系结构 注:Throwable是一个类,不是一个接口,这个类里面是描述的一些Error和Exception的共性,如图所示: 异常 / 错误是什么意思? 定义:指的是程序运行过程中,可能 ...
- 日常Java 2021/11/13
Java Applet基础 Applet是一种Java程序.它一般运行在支持Java的Web浏览器内.因为它有完整的Java API支持,所以Applet是一个全功能的Java应用程序.如下所示是独立 ...
- 打破砂锅问到底!HTTP和HTTPS详解
HTTP 引自维基百科HTTP:超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式.协作式和超媒体信息系统的应用层协议.HTTP是万维网的数 ...
- 【leetocode】55. Jump Game
You are given an integer array nums. You are initially positioned at the array's first index, and ea ...
- 集合类——集合输出、栈和队列及Collections集合
1.集合输出 在之前我们利用了toString()及get()方法对集合进行了输出,其实那都不是集合的标准输出,集合输出有四种方式:Iterator.ListIterator.Enumeration. ...
- Linux基础命令---nslookup查询域名工具
nslookup nslookup是一个查询DNS域名的工具,它有交互和非交互两种工作模式. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora. 1.语法 ...