乘积最大子数组

题目:乘积最大子数组

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

思考:

为什么不是用滑动窗口?

核心是滑动窗口的 "单调性前提" 不满足------ 乘积的特性导致窗口内的最值无法通过简单收缩窗口维护,这是滑动窗口失效的关键

滑动窗口能解决「子数组 / 子串最值问题」的核心前提是:

窗口内的目标值(和 / 积)随窗口扩大 / 收缩呈现 "单调性"(比如求最大和子数组,窗口扩大时和递增,收缩时和递减)。但乘积不满足这个前提:

  • 负数的存在:窗口内加入一个负数,乘积会由正变负;再加入一个负数,乘积又会由负变正 ------ 窗口的 "最大乘积" 无法通过简单的 "扩大右边界、收缩左边界" 维护;
  • 零的存在:窗口内遇到零,乘积直接归 0,需要重置窗口,但无法预判后续是否有更大的乘积;
  • 超时:如果强行用滑动窗口,需要枚举所有可能的窗口(O (n²) 时间复杂度),对于大数组(如 n=10⁵)必然超时。

动态规划(最优,O (n) 时间 + O (1) 空间)

核心思路是:维护两个状态(当前最大乘积、当前最小乘积),因为负数会让 "最小乘积" 变 "最大乘积",反之亦然。

核心逻辑:

dp_max[i]:以 nums[i] 结尾的子数组的最大乘积;

dp_min[i]:以 nums[i] 结尾的子数组的最小乘积;

状态转移:

plaintext

sql 复制代码
dp_max[i] = max(nums[i], dp_max[i-1]*nums[i], dp_min[i-1]*nums[i])
dp_min[i] = min(nums[i], dp_max[i-1]*nums[i], dp_min[i-1]*nums[i])

优化:无需数组存储 dp,只用两个变量滚动更新(空间 O (1))。

sql 复制代码
func maxProduct(nums []int) int {
    if len(nums) == 0 {
        return 0
    }
    // 初始化:第一个元素的最大/最小乘积都是自身
    curMax, curMin := nums[0], nums[0]
    res := nums[0] // 最终结果
    
    for i := 1; i < len(nums); i++ {
        // 临时保存curMax(因为更新curMin时会用到旧的curMax)
        temp := curMax
        // 状态转移:当前值、前最大*当前值、前最小*当前值 三者取最值
        curMax = max(nums[i], max(temp*nums[i], curMin*nums[i]))
        curMin = min(nums[i], min(temp*nums[i], curMin*nums[i]))
        // 更新全局最大乘积
        res = max(res, curMax)
    }
    return res
}

为什么要包含nums[i]自身:

若前序的 dp_max[i-1] 是负数,dp_max[i-1]*nums[i] 会比 nums[i] 更小,此时最优解是 nums[i] 本身;

相关推荐
Lionel6891 分钟前
分步实现 Flutter 鸿蒙轮播图核心功能(搜索框 + 指示灯)
算法·图搜索算法
小妖6665 分钟前
js 实现快速排序算法
数据结构·算法·排序算法
xsyaaaan7 分钟前
代码随想录Day30动态规划:背包问题二维_背包问题一维_416分割等和子集
算法·动态规划
zheyutao1 小时前
字符串哈希
算法
A尘埃1 小时前
保险公司车险理赔欺诈检测(随机森林)
算法·随机森林·机器学习
大江东去浪淘尽千古风流人物2 小时前
【VLN】VLN(Vision-and-Language Navigation视觉语言导航)算法本质,范式难点及解决方向(1)
人工智能·python·算法
努力学算法的蒟蒻3 小时前
day79(2.7)——leetcode面试经典150
算法·leetcode·职场和发展
2401_841495643 小时前
【LeetCode刷题】二叉树的层序遍历
数据结构·python·算法·leetcode·二叉树··队列
AC赳赳老秦3 小时前
2026国产算力新周期:DeepSeek实战适配英伟达H200,引领大模型训练效率跃升
大数据·前端·人工智能·算法·tidb·memcache·deepseek
2401_841495643 小时前
【LeetCode刷题】二叉树的直径
数据结构·python·算法·leetcode·二叉树··递归