# LinkedIn 高频算法面试:最大乘积子数组(Maximum Product Subarray|动态规划)
本文由 oavoservice 以面试复盘风格整理:用最短路径把思路讲清楚,并给出可直接默写的代码模板。
题目(改写版)
给定整数数组 nums,找一个连续子数组,使得其元素乘积最大,返回这个最大乘积。
示例:
- 输入:
[1, 2, -4, 1, 3, -2, 3, -1] - 输出:
48
为什么这题容易错
乘积遇到负数会“翻转”:
- 之前的最大值乘以负数可能变成最小值
- 之前的最小值乘以负数可能变成最大值
所以只维护一个 max 不够,必须同时维护 max_so_far 和 min_so_far。
核心思路(DP 一次遍历)
遍历到 x = nums[i] 时:
cur_max:以i结尾的最大乘积cur_min:以i结尾的最小乘积
转移:
new_max = max(x, x * cur_max, x * cur_min)new_min = min(x, x * cur_max, x * cur_min)
全局答案取遍历过程中的最大 cur_max。
复杂度
- 时间:
O(n) - 空间:
O(1)
Python 模板
from typing import List
def max_product(nums: List[int]) -> int:
if not nums:
return 0
cur_max = cur_min = ans = nums[0]
for x in nums[1:]:
# 注意:new_max/new_min 要基于旧值
a = x
b = x * cur_max
c = x * cur_min
new_max = max(a, b, c)
new_min = min(a, b, c)
cur_max, cur_min = new_max, new_min
ans = max(ans, cur_max)
return ans
面试官常追问
- 0 怎么处理?(公式里
max(x, x*...)本身就能让状态“重启”) - 为什么要同时维护 min?(负数翻转)
- 可否用分段法?(遇到 0 分段也行,但 DP 更简洁)
如果你准备 LinkedIn / Meta / Google 这类算法 VO,oavoservice 会重点训练“为什么要这样定义状态”,让你能在面试里讲得比写得更清楚。
需要面试真题? 立刻联系微信 Coding0201,获得真题。