↓快轉到主要內容
  1. LeetCode/

LeetCode 1458: Max Dot Product of Two Subsequences

·1 分鐘· ·
LeetCode Hard Dynamic-Programming Longest-Common-Subsequence Array
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-01-11

  • 提交紀錄:Wrong Answer → Accepted

解題思路
#

跟 LCS 一樣是兩個前綴的 DP(見 String DP)。dp[i][j] = 用 nums1[:i] 和 nums2[:j] 的非空子序列能得到的最大點積:

  • 配對 nums1[i-1] 和 nums2[j-1]:p = nums1[i-1] × nums2[j-1],可以接在前面的最佳值後面 dp[i-1][j-1] + p,或自己開頭 p(前面都是負的時候比較好)。
  • 跳過 nums1[i-1]:dp[i-1][j]。
  • 跳過 nums2[j-1]:dp[i][j-1]。

子序列不能是空的,所以初始值是負無限大,不是 0。這也是為什麼要有「自己開頭」的選項:如果所有乘積都是負的,答案是最大的那個負數,不是 0。

我的嘗試
#

第一版只有「配對」和 dp[i-1][j-1](兩個都跳過),沒有只跳過其中一個的轉移。這樣 dp[i][j] 只看得到兩邊同時往前的情況,nums1[i] 沒辦法跟 nums2 前面的元素配對之後再繼續。例如 nums1 = [3, 1, 3]、nums2 = [3, 4]:3 × 3 + 3 × 4 = 21,這版回傳 15。

正確解法
#

class Solution:
    def maxDotProduct(self, nums1: List[int], nums2: List[int]) -> int:
        n, m = len(nums1), len(nums2)
        NEG = float("-inf")
        dp = [[NEG] * (m + 1) for _ in range(n + 1)]   # 子序列不能是空的
        for i in range(1, n + 1):
            for j in range(1, m + 1):
                p = nums1[i - 1] * nums2[j - 1]
                dp[i][j] = max(
                    p,                             # 從這一對開始
                    dp[i - 1][j - 1] + p,          # 接在前面後面
                    dp[i - 1][j],                  # 跳過 nums1[i-1]
                    dp[i][j - 1],                  # 跳過 nums2[j-1]
                )
        return dp[n][m]

複雜度
#

時間 O(nm),空間 O(nm)。

要特別避免的錯誤
#

  • 少了「只跳過其中一個」的轉移。
  • 初始值用 0:子序列不能是空的,全部都是負數時答案是負的。

面試口說整理
#

這是兩個前綴的 DP。dp[i][j] 可以配對這兩個元素,接在前面的最佳值後面或自己開頭;也可以跳過其中一邊的元素。因為子序列不能是空的,初始值用負無限大,而且要保留「自己開頭」的選項,處理全部都是負數的情況。時間 O(nm)。

相關文章

LeetCode 42: Trapping Rain Water
·1 分鐘
LeetCode Hard Array Two-Pointers Dynamic-Programming Stack
LeetCode 42 解題筆記:每格能存的水是 min(左邊最高, 右邊最高) - 自己的高度;用前後綴最大值或左右雙指針
LeetCode 84: Largest Rectangle in Histogram
·1 分鐘
LeetCode Daily Hard Array Stack Monotonic-Stack Dynamic-Programming Geometry Histogram
使用單調堆疊解決直方圖中最大矩形面積問題
LeetCode 220: Contains Duplicate III
·2 分鐘
LeetCode Hard Sliding-Window Bucket-Sort Ordered-Set Sorting Array
LeetCode 220 解題筆記:桶大小設成 valueDiff + 1,同一個桶裡的兩個數一定符合;只要再看相鄰兩個桶。視窗只保留最近 indexDiff 個數,所以每個桶最多一個數
LeetCode 2709: Greatest Common Divisor Traversal
·2 分鐘
LeetCode Hard Math Number-Theory Union-Find Sieve Gcd Array
LeetCode 2709 解題筆記:任兩個 index 都能互通 ⇔ 全部在同一個連通塊;用 SPF 分解質因數,數字跟它的質因數在 Union-Find 裡合併;1 要特別處理
LeetCode 135: Candy
·1 分鐘
LeetCode Hard Greedy Array
LeetCode 135 解題筆記:左往右掃一次滿足左鄰居、右往左掃一次滿足右鄰居,每個人取兩者較大值
LeetCode 3638: Maximum Balanced Shipments
·1 分鐘
LeetCode Medium Dynamic-Programming Greedy Monotonic-Stack Array
LeetCode 3638 解題筆記:貪心,一段一旦出現比這段最大值小的數就馬上切;因為切之前的那段是非遞減的,最大值就是前一個數