一、题目解析
根据示例nums数组中存在负数,下面分析时需注意
二、算法原理
1、状态表示
此时f[i]表示:以i位置为结尾的所有子数组中的最大乘积,但是由于nums中存在负数,所以还需要g[i]表示:以i位置为结尾的所有子数组中的最小乘积
2、状态转移方程
f[i]=max(nums[i],max(f[i-1]*nums[i],g[i-1]*nums[i]))
g[i]的分析过程差不多这里直接给出
g[i]=min(nums[i],min(g[i-1]*nums[i],f[i-1]*nums[i]))
3、初始化
由于要使用f[i-1]和g[i-1]所以可以选择直接初始化f[0]和g[0],也可以使用虚拟节点,即开辟空间时多开辟一个,用于初始化计算,且为了计算结果不影响后面填表,所以初始化为1,尤为注意我们初始化加了一格,下标的映射关系改变。
4、填表顺序
为了保证所需值已被计算,从左往右,两个表一起填。
5、返回值
根据题目要求我们只需要返回f表中的最大值即可
代码能力是需要实操的,坚持下来,152. 乘积最大子数组 - 力扣(LeetCode)
三、代码示例
class Solution {
public:
int maxProduct(vector<int>& nums) {
int n = nums.size();
vector<int> f(n+1,1),g(n+1,1);
for(int i = 1;i<=n;i++)
{
f[i]=max(nums[i-1],max(f[i-1]*nums[i-1],g[i-1]*nums[i-1]));
g[i]=min(nums[i-1],min(f[i-1]*nums[i-1],g[i-1]*nums[i-1]));
}
int f_max = f[1];
for(int i = 2;i<=n;i++)
{
if(f[i]>f_max) f_max = f[i];
}
return f_max;
}
};
看到最后,如果对您有所帮助,还请点赞、收藏和关注,点点关注不迷路,我们下期再见!