題目描述:給定一個未排序的整數陣列 nums,回傳其中最長遞增子序列(LIS)的個數。
解題思路:使用動態規劃,定義兩個陣列:
len[i]:以 nums[i] 結尾的最長遞增子序列長度。cnt[i]:以 nums[i] 結尾的最長遞增子序列個數。對每個 i,遍歷所有 j < i:
nums[j] < nums[i],可以接在 j 後面。len[j] + 1 > len[i],找到更長的子序列,更新 len[i] 並設 cnt[i] = cnt[j]。len[j] + 1 == len[i],找到等長的子序列,cnt[i] += cnt[j]。最後,統計所有 len[i] 等於全域最大長度的 cnt[i] 之和。
時間複雜度:O(n^2) — 雙層迴圈遍歷所有配對。
空間複雜度:O(n) — 兩個長度為 n 的輔助陣列。
1. Initialize len[i] = 1, cnt[i] = 1 for all i
2. For i from 1 to n-1:
a. For j from 0 to i-1:
- If nums[j] < nums[i]:
- If len[j] + 1 > len[i]: len[i] = len[j] + 1, cnt[i] = cnt[j]
- Else if len[j] + 1 == len[i]: cnt[i] += cnt[j]
b. Update maxLen = max(maxLen, len[i])
3. Sum cnt[i] for all i where len[i] == maxLen
4. Return sum線段樹 / BIT 優化:使用線段樹或樹狀陣列維護 (length, count) 的對映,對值域查詢最大長度及其計數,可將時間複雜度降至 O(n log n)。實作較複雜,適合 n 較大的場景。
Patience Sorting 變體:類似 LIS 的二分搜尋解法,但需要額外記錄每個位置的計數,實作更為複雜。