解題說明
Count Ways to Group Overlapping Ranges
題目描述:給定一組區間 ranges,其中 ranges[i] = [start, end]。將這些區間分為兩組,使得同一組中任意兩個區間不重疊(端點接觸算重疊)。回傳滿足條件的分組方式數,答案對 10^9 + 7 取模。
解題思路:
- 先將區間排序(按起點),並合併所有互相重疊的區間,得到若干不相交的「合併超區間」。
- 同一個合併超區間內的所有原始區間,必須放在同一組(因為任意兩個互相接觸或重疊)。
- 每個合併超區間可以獨立選擇放入第 1 組或第 2 組,共 2 種選擇。
- 設合併後有
k個超區間,則分組方式共2^k(mod10^9+7)。
關鍵:只需計算合併後的超區間數量 k,不需要實際輸出分組。端點接觸(start[j] <= end[i])算重疊,需合併。
C++ 解法
複雜度分析
時間複雜度:O(n log n) — 排序需 O(n log n),合併掃描需 O(n),快速冪 O(log n),整體由排序主導。
空間複雜度:O(1) — 只使用常數個額外變數(除排序的棧空間外)。
虛擬碼
1. Sort ranges by start endpoint. 2. Initialize groups = 0, maxEnd = -1. 3. For each range [s, e] in sorted order: a. If s > maxEnd: groups++ (new connected component). b. maxEnd = max(maxEnd, e). 4. Compute ans = 2^groups mod (10^9+7). 5. Return ans.
其他解法
方法一:Union-Find(並查集)
對每對互相重疊的區間合併(Union),最後統計連通分量數 k,答案為 2^k。時間複雜度 O(n^2 * α(n))(兩兩比較),不如排序後線性掃描高效,但概念上更直觀地體現「互相鎖定」的結構。
方法二:快速冪計算指數
對合併後 k 個超區間,用快速冪(binary exponentiation)計算 2^k mod p,時間 O(log k),比逐步乘法快。對本題 k 最大約 10^5,差距不大,但養成良好習慣。
方法三:圖連通分量 建構區間重疊圖(點為區間,邊為重疊關係),用 BFS/DFS 找連通分量數。時間 O(n^2),空間 O(n^2),遠不如排序法,僅用於理解問題結構。
延伸思考
- 若分組數不限於 2 而是 k 組,每組中任意兩個區間不重疊,答案公式如何變化?
- 本題與「計算重疊區間的連通分量數」等價,如果區間是動態插入的,如何用動態資料結構維護連通分量數?
- 若重疊定義改為「嚴格相交」(端點接觸不算),算法需要如何修改?