Medium草稿★★★★★O(n log n) 時間 · O(1) 空間
GreedySortingDynamic Programming
Patterns🪙 貪心🔢 排序後處理
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

646Maximum Length of Pair ChainGreedyMediumGreedy

給定 n 個數對 pairs,其中 pairs[i] = [left_i, right_i]left_i < right_i。如果 b < c,則可以將 [a, b][c, d] 串成鏈。回傳最長數對鏈的長度。

Example:

Input: pairs = [[1,2],[2,3],[3,4]] Output: 2 (例如 [1,2] -> [3,4])

Intuition

TIP

按右端點排序,貪心選結束最早的數對 — 與「活動選擇問題」相同。

Approaches

1. DP — O(n^2) / O(n)
  • Idea: 按左端點排序,dp[i] 表示以第 i 個數對結尾的最長鏈。對每個數對向前找能接上的。
  • Time: O(n^2)
  • Space: O(n)
class Solution {
    fun findLongestChain(pairs: Array<IntArray>): Int {
        pairs.sortBy { it[0] }
        val n = pairs.size
        val dp = IntArray(n) { 1 }

        for (i in 1 until n) {
            for (j in 0 until i) {
                if (pairs[j][1] < pairs[i][0]) {
                    dp[i] = maxOf(dp[i], dp[j] + 1)
                }
            }
        }
        return dp.max()
    }
}
⭐ 2. Greedy (sort by right endpoint) — O(n log n) / O(1)
  • Idea: 按右端點排序,貪心選擇:若當前數對的左端點大於上一個選的右端點,就選它。
  • Time: O(n log n)
  • Space: O(1)
class Solution {
    fun findLongestChain(pairs: Array<IntArray>): Int {
        pairs.sortBy { it[1] }
        var count = 1
        var end = pairs[0][1]

        for (i in 1 until pairs.size) {
            if (pairs[i][0] > end) {
                count++
                end = pairs[i][1]
            }
        }
        return count
    }
}

🔑 Takeaways