题目

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.

Subscribe to see which companies asked this question

分析

最大字段积问题,之前我们熟悉的题目是求最大字段和。其实,他们本质是相同的,应该属于动态规划的范畴。

方法一(遗憾的TLE):

由于最终的最大乘积结果可能是从0~size-1的任何一个位置开始的子数组,所以我们可以先求出从0~siz-1开始的每个位置到最终位置的最大乘积,保存起来。

然后遍历该最大乘积数组,找出其中的最大值。

该方法复杂度有O(n^2)吧,遗憾的是,TLE了。。。

方法二:

不得不再次思考效率高的算法:

我们知道对序列元素遍历到 i 时,其值可正可负;

最大值可能是:

1. 前面子序列最大正乘积 * 正值;

2. 前面子序列最小负乘积 * 负值;

也就是说:其实子数组乘积最大值的可能性为:累乘的最大值碰到了一个正数;或者,累乘的最小值(负数),碰到了一个负数。所以每次要保存累乘的最大(正数)和最小值(负数)。

同时,还有一个选择起点的逻辑,如果之前的最大和最小值同当前元素相乘之后,没有当前元素大(或小)那么当前元素就可作为新的起点。例如,前一个元素为0的情况,{1,0,9,2},到9的时候9应该作为一个最大值,也就是新的起点,{1,0,-9,-2}也是同样道理,-9比当前最小值还小,所以更新为当前最小值。

TLE代码

class Solution {
public:
int maxProduct(vector<int>& nums) {
if (nums.empty())
return 0; int size = nums.size();
//求从0~size-1处开始,每处能够得到的最大子数组乘积
vector<int> maxP(size, 1);
for (int i = 0; i < size; ++i)
{
maxP[i] = nums[i];
}//for for (int i = 0; i < size; ++i)
{
int curP = maxP[i]; for (int j = i + 1; j<size; ++j)
{
curP *= nums[j];
if (maxP[i] < curP)
maxP[i] = curP;
}
}//for //找到最大子数组乘积中的最大乘积值
int maxRet = maxP[0];
for (int i = 1; i < size; ++i)
{
if (maxP[i] > maxRet)
maxRet = maxP[i];
}//for
return maxRet;
}
};

AC代码

class Solution {
public:
//方法一:遗憾的TLE
int maxProduct1(vector<int>& nums) {
if (nums.empty())
return 0; int size = nums.size();
//求从0~size-1处开始,每处能够得到的最大子数组乘积
vector<int> maxP(size, 1);
for (int i = 0; i < size; ++i)
{
maxP[i] = nums[i];
}//for for (int i = 0; i < size; ++i)
{
int curP = maxP[i]; for (int j = i + 1; j<size; ++j)
{
curP *= nums[j];
if (maxP[i] < curP)
maxP[i] = curP;
}
}//for //找到最大子数组乘积中的最大乘积值
int maxRet = maxP[0];
for (int i = 1; i < size; ++i)
{
if (maxP[i] > maxRet)
maxRet = maxP[i];
}//for
return maxRet;
} //方法二:时间复杂度为O(n)
int maxProduct(vector<int>& nums) {
if (nums.empty())
return 0; int size = nums.size(); //存储最大子数组乘积,当前最大、最小值
int maxRetP = nums[0], curMaxP = nums[0], curMinP = nums[0];
for (int i = 1; i < size; ++i)
{
int tmpMax = curMaxP * nums[i];
int tmpMin = curMinP * nums[i]; //更新当前最大、最小值
curMaxP = max(max(tmpMax , tmpMin), nums[i]);
curMinP = min(min(tmpMax , tmpMin), nums[i]); //更新当前最大子数组结果
maxRetP = max(maxRetP, curMaxP);
}//for
return maxRetP;
}
};

GitHub测试程序源码

LeetCode(152) Maximum Product Subarray的更多相关文章

  1. LeetCode(53) Maximum Subarray

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

  2. LeetCode之“动态规划”:Maximum Product Subarray

    题目链接 题目要求: Find the contiguous subarray within an array (containing at least one number) which has t ...

  3. LeetCode(164)Maximum Gap

    题目 Given an unsorted array, find the maximum difference between the successive elements in its sorte ...

  4. LeetCode(104) Maximum Depth of Binary Tree

    题目 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the l ...

  5. LeetCode Maximum Product Subarray(枚举)

    LeetCode Maximum Product Subarray Description Given a sequence of integers S = {S1, S2, . . . , Sn}, ...

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

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

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

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

  8. 152. Maximum Product Subarray - LeetCode

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

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

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

随机推荐

  1. PHP&Java 调用C#的WCF

    步骤一:用C#声明WCF [ServiceContract] public interface IService1 { [OperationContract] void DoWork(); [Oper ...

  2. ruby 正则表达式 匹配所有符合规则的信息

    假设一个字符串当中有很多符合规则的信息,下面的例子可以把所有匹配到的结果打印出来: message="afhadhffkdf414j9tr3j43i3433094jwoert223jwew1 ...

  3. eclipse查看jar包源文件

    话不多说上链接 https://www.cnblogs.com/1995hxt/p/5252098.html这里介绍了完整的流程,亲自试过,可以的! 以防以后要用的时候找不到文件的下载地址,所以就先在 ...

  4. BigDecimal的加减乘除

    Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更小的数进行 ...

  5. <img/>标签属性

    属性        属性值               描述 src            url               图像的路径 alt             文本            ...

  6. 就来推荐一本2018年研究的Web书《移动Web前端高效开发实战》

    一线互联网公司Web前端团队实战经验总结,涵盖移动Web前端开发各个关键技术环节,包括移动开发核心技术.常用布局方案.MV*类新时代框架.预编译技术.性能优化.开发调试.混合式应用.单元测试.工程化等

  7. countUp 动画展示数字变化

    html <p id="countUp" style="font-size:25px;height:25px;background-color:#0aa;" ...

  8. 如何处理VirtualBox启动错误消息:The vboxdrv kernel module is not loaded

    我在启动minikube时,遇到如下错误消息: Starting local Kubernetes v1.10.0 cluster... Starting VM... E1010 03:27:37.9 ...

  9. iOS 微信和支付宝关于回调处理

    在支付这一块,发现讲支付集成的比较多,但是关于支付后回调处理的不多见,(当时因为这个问题懵逼了好久)就自己总结一下, 1.支付宝回调 支付宝的回调想对来说比较简单一些,因为支付宝的回调就在调起支付宝的 ...

  10. lca(最近公共祖先(在线)) 倍增法详解

    转自大佬博客 : https://blog.csdn.net/lw277232240/article/details/72870644 描述:倍增法用于很多算法当中,通过字面意思来理解 LCA是啥呢 ...