解題說明
String Compression
題目描述:原地壓縮字元陣列 chars:連續相同字元只保留一個,若出現次數 > 1 則在其後附上次數的各位數字,最終回傳壓縮後的長度。
解題思路:用三個指標:read 掃描原始陣列,write 指向寫入位置,anchor 標記每段連續字元的起點。每當字元改變或到達末尾,就將字元寫入 write,若長度 > 1 則逐位寫入數字。全程原地操作,空間 O(1)。
C++ 解法
複雜度分析
時間複雜度:O(n) — read 指標遍歷整個陣列一次,數字轉字串的長度最多 O(log n),整體 O(n)。
空間複雜度:O(log n) — to_string 暫時使用 O(log n) 空間存數字字串;若手動逐位計算可降至 O(1)。
虛擬碼
1. write = 0, anchor = 0, n = len(chars)
2. For read from 0 to n (inclusive):
a. If read == n or chars[read] != chars[anchor]:
- chars[write++] = chars[anchor]
- count = read - anchor
- If count > 1: write each digit of count into chars[write++]
- anchor = read
3. Return write其他解法
兩次掃描:第一次計算壓縮後長度,第二次執行壓縮。實作稍繁瑣但邏輯更清晰,空間仍 O(1)。
groupby 模擬:用類似 Python itertools.groupby 的思路,收集每組 (字元, 次數) 後重建。需要 O(n) 額外空間,不符合原地要求。
延伸思考
- 若壓縮後反而比原始更長(如單一字元),是否還需要壓縮?題目如何保證長度不增加?
- 如何實作「解壓縮」的逆操作,還原成原始字元陣列?
- 若字元集不限於英文字母(如包含數字字元),壓縮格式應如何調整以避免歧義?