本文由 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,獲得真題。