题目

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. NET?.NET Framework?.NET Core?

    什么是.NET?什么是.NET Framework?什么是.NET Core? https://www.cnblogs.com/1996V/p/9037603.html 什么是.NET?什么是.NET ...

  2. 转 Oracle 11g Rman – 08317错误

    在一次帮助客户解决归档满的过程中遭遇了此错误. 客户是新上线系统,11g版本.设置了归档清除脚本(脚本参考:http://www.ludatou.com/?p=766),结果发现以往没问题的脚本在此刻 ...

  3. mysql 5.1 在Windows下重置root 用户密码

    在windows下:打开命令行窗口,停止mysql服务(这里不用进入mysql目录): net stop mysql 进入mysql安装目录的bin文件夹下 执行: mysqld --skip-gra ...

  4. canvas前端压缩图片

    参考网上的用法,下面是利用canvas进行的图片压缩 <!DOCTYPE html> <html> <head> <meta charset="ut ...

  5. ML.NET 示例:目录

    ML.NET 示例中文版:https://github.com/feiyun0112/machinelearning-samples.zh-cn 英文原版请访问:https://github.com/ ...

  6. idea报错:Error running $classname: Command line is too long. Shorten command line for $classname.

    Command line is too long 打印的变量太长了,超过了限制,这都会报错...我只想知道idea基于什么原理会报这个错... 解决 1.按照提示修改该类的配置,选择jar manif ...

  7. html学习笔记-XML

    html学习笔记-XML Table of Contents 1. XML简介 2. XML用途 3. XML树结构 4. XML语法 5. XML元素 6. XML属性 7. XML验证 8. XM ...

  8. 1g免费空间永久使用

    云邦互联免费空间(免备案,无广告) [1G免费全能空间,免备案,无广告] 1G全能空间 + 100M数据库(Mysql 5.5 / SQL Server 2005) 支持的脚本:ASP.PHP(5.2 ...

  9. 9、数值的整数次方------------>剑指offer系列

    数值的整数次方 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 思路 这道题逻辑上很简单,但很容易出错 关键是要考虑全面,考虑到所有情况 ...

  10. JavaScript_4_数据类型

    1. JavaScript对大小写敏感. 2. JavaScript是脚本语言.浏览器会在读取代码时,逐行地执行脚本代码.而对于传统编程来说,会在执行前对所有代码进行编译. 3. 变量什么用var, ...