Medium草稿★★★★★O(n log n) 時間 · O(n) 空間
Dynamic ProgrammingBinary SearchArray
Patterns🎯 二分搜尋📈 線性 DP・Kadane
尚未複習過

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

300Longest Increasing Subsequence1-D DPMedium1-D DP

給定一個整數陣列 nums,找出最長嚴格遞增子序列的長度。子序列不需要連續但需保持原始順序。

Example:

Input: nums = [10,9,2,5,3,7,101,18] Output: 4

Intuition

TIP

DP 解法:以每個元素結尾的 LIS 長度;進階:用 patience sorting 搭配二分搜尋做到 O(n log n)。

Approaches

1. DP O(n^2) — O(n^2) / O(n)
  • Idea: dp[i] = 以 nums[i] 結尾的最長遞增子序列長度
  • Time: O(n^2)
  • Space: O(n)
class Solution {
    fun lengthOfLIS(nums: IntArray): Int {
        val dp = IntArray(nums.size) { 1 }
        for (i in 1 until nums.size) {
            for (j in 0 until i) {
                if (nums[j] < nums[i]) {
                    dp[i] = maxOf(dp[i], dp[j] + 1)
                }
            }
        }
        return dp.max()
    }
}
⭐ 2. Patience Sorting + Binary Search — O(n log n) / O(n)
  • Idea: 維護遞增的 tails 陣列,用二分搜尋決定插入或替換位置
  • Time: O(n log n)
  • Space: O(n)
class Solution {
    fun lengthOfLIS(nums: IntArray): Int {
        val tails = mutableListOf<Int>()
        for (num in nums) {
            var lo = 0; var hi = tails.size
            while (lo < hi) {
                val mid = (lo + hi) / 2
                if (tails[mid] < num) lo = mid + 1 else hi = mid
            }
            if (lo == tails.size) tails.add(num) else tails[lo] = num
        }
        return tails.size
    }
}

🔑 Takeaways

Ladders 看全部 →

📐

最長遞增子序列

O(n²) DP 到計數變體。

  1. 1
  2. 2#673Number of Longest Increasing SubsequenceMediumLIS 的數量:DP 額外記計數