解題說明
Missing Ranges
題目描述:給定一個已排序(遞增)的整數陣列 nums,以及範圍的下界 lower 和上界 upper。找出所有在 [lower, upper] 範圍內、但不在 nums 中出現的缺失範圍,以字串列表回傳。每個缺失範圍格式為 "a" 或 "a->b"(a < b)。
解題思路:線性掃描,逐段比較相鄰的「邊界」與陣列元素之間的空隙。
將問題轉化為檢查以下每個區間:[lower, nums[0]-1]、[nums[i]+1, nums[i+1]-1](對每對相鄰元素)、以及 [nums[n-1]+1, upper]。
為了統一處理邊界,可在陣列前插入 lower-1,在陣列後插入 upper+1,然後對相鄰對 (prev, curr) 檢查:若 curr - prev >= 2,代表 prev+1 到 curr-1 是一段缺失範圍。注意整數溢出:使用 long long 處理邊界值 lower-1 和 upper+1。
C++ 解法
複雜度分析
時間複雜度:O(n) — 只需一次線性掃描陣列,每個元素處理一次,字串建構為 O(log U)(數字位數),整體為 O(n log U),通常視為 O(n)。
空間複雜度:O(1) — 除回傳結果外,只使用常數個額外變數(prev、curr)。
虛擬碼
1. Initialize result = [], prev = lower - 1.
2. For i from 0 to n (inclusive):
a. If i < n: curr = nums[i]. Else: curr = upper + 1.
b. If curr - prev >= 2:
- lo = prev + 1, hi = curr - 1.
- If lo == hi: append to_string(lo) to result.
- Else: append to_string(lo) + "->" + to_string(hi) to result.
c. prev = curr.
3. Return result.其他解法
方法一:顯式插入哨兵
在 nums 前後插入 lower-1 和 upper+1,形成長度 n+2 的陣列,再對相鄰對線性掃描。邏輯更直觀,但需要額外 O(n) 空間(或修改輸入)。
方法二:逐步推進 lower
用一個指針 cur = lower,對 nums 中每個元素:若 cur < nums[i],記錄缺失範圍 [cur, nums[i]-1];若 cur == nums[i],則前進;處理完後若 cur <= upper,記錄剩餘缺失範圍。邏輯清晰,複雜度相同。
方法三:集合查找(僅供理解)
將 nums 存入哈希集合,對 [lower, upper] 逐一判斷每個整數是否缺失,再合併連續缺失段。時間 O(upper - lower),適合範圍極小的情況,但一般不實用。
延伸思考
- 若
nums可能含有重複元素,如何修改算法確保正確性? - 若需要輸出第 k 個缺失範圍而非所有,是否有辦法不生成全部結果而直接定位?
- 如何擴展此問題到二維矩陣:找出在矩形範圍
[r1,r2] x [c1,c2]內缺失的座標對?