【Leetcode】乘积最大子数组

1 题目

给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续 子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

测试用例的答案是一个 32-位 整数。

请注意,一个只包含一个元素的数组的乘积是这个元素的值。

示例 1:

输入: nums = 2,3,-2,4

输出: 6

解释: 子数组 2,3 有最大乘积 6。

示例 2:

输入: nums = -2,0,-1

输出: 0

解释: 结果不能为 2, 因为 -2,-1 不是子数组。

2 分析

寻找连续子数组,第一反应是用动态规划:

dpi=max(dpi−1∗numsi,dpi−1,numsi)dpi = max(dpi-1*numsi,dpi-1,numsi)dpi=max(dpi−1∗numsi,dpi−1,numsi)

进一步分析,如果dpi−1∗numsi<dpi−1dpi-1*numsi<dpi-1dpi−1∗numsi<dpi−1,其实有两种情况:

  • numsi<0,dpi−1>0numsi<0,dpi-1>0numsi<0,dpi−1>0,那么dpi=dpi−1dpi =dpi-1dpi=dpi−1
  • numsi>0,dpi−1<0numsi>0,dpi-1<0numsi>0,dpi−1<0,那么dpi=numsidpi =numsidpi=numsi

但有个问题,如果是第一种情况,那么如果numsi+1numsi+1numsi+1也小于0,dpi+1dpi+1dpi+1的最优取值应该是dpi−1∗numsi∗numsi+1dpi-1*numsi*numsi+1dpi−1∗numsi∗numsi+1,但这是无法用上面动态规划的公式得到的。所以,真正的动态规划公式应该是

dpij=max⁡k=i+1j−1{dpik∗dpk+1j}dpij = \max_{k=i+1}^{j-1}\{dpik*dpk+1j\}dpij=k=i+1maxj−1{dpik∗dpk+1j}

但这个公式好像更复杂了,需要罗列路径上所有的k,计算量很大。

仔细思考下,为什么我们不能认为数组长度增加,乘积一定变大呢?是因为新增的数组值可能为负,这个时候最大值需要通过之前的最小值计算得到。所以这题的关键是:当前最小的乘积,遇到负数后,可能变成最大的乘积。

因此,需要同时记录当前的最大值和最小值,另外需要ans记录目前乘积最大的值(有可能当前最大值超过不了历史最大值)。综上,动态规划的公式为

curMax=max⁡(x,curMax∗x,curMin∗x) \text{curMax} = \max(x, \text{curMax}*x, \text{curMin} *x) curMax=max(x,curMax∗x,curMin∗x)

curMin=min⁡(x,curMax∗x,curMin∗x) \text{curMin} = \min(x, \text{curMax}*x, \text{curMin} *x) curMin=min(x,curMax∗x,curMin∗x)

python 复制代码
def maxProduct(nums):
    n = len(nums)
    if n==1:
        return nums[0]
    ans, curMax, curMin = nums[0], nums[0], nums[0]
    for i in range(1,n):
        x = nums[i]
        print(x, curMax, curMin, ans)
        newMax = max(x, curMax * x, curMin * x)
        newMin = min(x, curMax * x, curMin * x)
        curMax, curMin = newMax, newMin
        ans = max(ans, curMax)
        print(curMax, curMin, ans)
    return ans
相关推荐
ZhengEnCi2 小时前
Agent 架构怎么选:从单 Agent 到多 Agent 编排的选型决策指南
算法·架构
秋天的怀念_David2 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Pniubi3 小时前
力扣283移动零(双指针法)
算法·leetcode·职场和发展
hhb_6183 小时前
大模型落地三重优化实战
人工智能·算法·机器学习
云和数据.ChenGuang3 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
2601_970703834 小时前
工业除湿机租赁:把一份租金合同拆开看
大数据·数据结构·算法·数据库架构·推荐算法
心中有你02144 小时前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
ZhengEnCi6 小时前
同样的模型,为什么本地和云 API 差别那么大:量化精度、聊天模板与采样参数的三大元凶
人工智能·算法·llm
Flynn Liang6 小时前
RAG 答非所问/幻觉怎么破?Spring AI QuestionAnswerAdvisor 召回优化实战(TopK/重排/混合检索)
人工智能·算法·spring·rag·幻觉·springai
liminla!6 小时前
SQL 从入门到进阶:语法速查与实战练习(完整优化版)
数据库·sql·算法