【LeetCode】最大子数组乘积:三种解法从暴力到最优

给定一个包含正数、负数和零的数组 arr[],找出任意连续子数组的最大乘积。

示例:

  • 输入:arr[] = [-2, 6, -3, -10, 0, 2] → 输出:180(子数组 [6, -3, -10],乘积 = 6 * (-3) * (-10) = 180)
  • 输入:arr[] = [-1, -3, -10, 0, 6] → 输出:30(子数组 [-3, -10],乘积 = (-3) * (-10) = 30)
  • 输入:arr[] = [2, 3, 4] → 输出:24(全正数时结果为所有元素乘积)

目录

  • [暴力解法:两层循环 O(n²)](#暴力解法:两层循环 O(n²))
  • [最优解法1:维护最小和最大乘积 O(n)](#最优解法1:维护最小和最大乘积 O(n))
  • [最优解法2:双向遍历 O(n)](#最优解法2:双向遍历 O(n))

刷 LeetCode 遇到"最大子数组乘积"这种题,动态规划思路绕来绕去,光看文字解析太抽象了。别只靠硬想,可以试试图码,它把60多种数据结构和算法做成了交互式动画,输入数据就能看到每一步怎么变。尤其适合备战408考研数据结构期末考试 ,连C/C++/Java/Python代码都能上传,生成可视化解析,随时选中代码还能问AI。想彻底搞懂这类题,去图码看看,直观多了。

图码-数据结构与算法交互式可视化平台

访问网站:https://totuma.cn

暴力解法:两层循环 O(n²)

最直接的想法:遍历所有连续子数组,计算每个子数组的乘积,记录最大值。

代码(简化版):

python 复制代码
def maxProduct(arr):
    n = len(arr)
    maxProd = arr[0]
    for i in range(n):
        mul = 1
        for j in range(i, n):
            mul *= arr[j]
            maxProd = max(maxProd, mul)
    return maxProd

时间复杂度: O(n²),空间复杂度:O(1)。


最优解法1:维护最小和最大乘积 O(n)

核心思路:遍历数组时,同时维护两个变量------以当前元素结尾的子数组的最大乘积最小乘积

  • 遇到零会重置乘积(任何包含零的子数组乘积为零)。
  • 遇到负数时,最小乘积可能变成最大乘积(因为负负得正)。
  • 通过同时维护最大和最小,可以在一次遍历中正确计算。

代码(简化版):

python 复制代码
def maxProduct(arr):
    n = len(arr)
    currMax = arr[0]
    currMin = arr[0]
    maxProd = arr[0]
    for i in range(1, n):
        temp = max(arr[i], arr[i] * currMax, arr[i] * currMin)
        currMin = min(arr[i], arr[i] * currMax, arr[i] * currMin)
        currMax = temp
        maxProd = max(maxProd, currMax)
    return maxProd

时间复杂度: O(n),空间复杂度:O(1)。


最优解法2:双向遍历 O(n)

另一种思路:从左到右和从右到左各遍历一次,累积乘积。遇到零时重置为1。

  • 当有奇数个负数时,乘积为负,我们只能舍弃第一个或最后一个负数。
  • 双向遍历可以覆盖这两种情况,取最大值。

代码(简化版):

python 复制代码
def maxProduct(arr):
    n = len(arr)
    maxProd = float('-inf')
    leftToRight = 1
    rightToLeft = 1
    for i in range(n):
        if leftToRight == 0:
            leftToRight = 1
        if rightToLeft == 0:
            rightToLeft = 1
        leftToRight *= arr[i]
        j = n - i - 1
        rightToLeft *= arr[j]
        maxProd = max(leftToRight, rightToLeft, maxProd)
    return maxProd

时间复杂度: O(n),空间复杂度:O(1)。


总结: 三种方法从 O(n²) 优化到 O(n),面试中推荐使用维护最小和最大乘积的方法,思路清晰且不易出错。双向遍历法也很巧妙,可以作为备选方案。

相关推荐
wen_zhufeng11 分钟前
IndexTTS 2.5 技术报告
人工智能·算法·机器学习
大熊背1 小时前
树莓派相机自动白平衡详解(四)
算法·树莓派·白平衡·isppipeline
一米阳光86611 小时前
软考(中级)软件设计师核心笔记(9)算法——背包问题
笔记·算法·职场发展·软考·软件设计师·中级职称
晚风醉蝶1 小时前
1-11-奇偶排序-OddEvenSort
java·数据结构·算法
旖旎夜光1 小时前
LeetCode 852:山脉数组的峰顶索引(二分查找) —— 题解
数据结构·c++·算法·leetcode·二分查找
HY小宝F2 小时前
树莓派 FFmpeg 实战笔记(二):命令行、源码编译与硬件编码的真相
学习·职场和发展·ffmpeg
程序员三藏3 小时前
浅谈性能测试
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·性能测试
小雪崩3 小时前
嵌入式学习 day25:哈希表及排序与查找
linux·c语言·数据结构·学习·排序算法
白露与泡影3 小时前
解密 Pi 的 Harness 工程:Agent 会话如何实现持久化与恢复
java·人工智能·算法
happyprince5 小时前
01-整体观-Codex全貌解读(源码)
算法·ai编程