443. String Compression

練習日期:2026-01-28

難度:Medium

類型:Two Pointers、String

📘 題目敘述

給定一個字元陣列 chars,請你使用 原地(in-place) 的方式壓縮它。

壓縮規則:

  • 對於每一段連續重複的字元:
    • 先寫入該字元
    • 若該字元連續出現的次數大於 1,再把次數(以字元形式)依序寫入
    • 例如 12 會寫成 '1''2'
  • 最後回傳壓縮後的新長度
  • 你必須在輸入陣列 chars 上直接修改內容,且只能使用 常數額外空間

條件限制

  • 1 ≤ chars.length ≤ 2000
  • chars[i] 是小寫英文字母、大寫英文字母、數字或符號

🧠 解題思路

我用的是「一邊掃描原本的 chars,一邊把壓縮結果寫回 chars 前面」的做法。

核心概念是:

  • now 記錄「目前這一段在統計的字元是誰」
  • count 記錄「這個字元連續出現了幾次」
  • all 當作「寫入指標」:壓縮後的內容都寫回 chars[0..all-1]

一旦遇到新字元(chars[i] != now):

  • 代表上一段結束,要把上一段的 count(如果 > 1)寫回去
  • 再開始新的段落

最後迴圈跑完後,還要把「最後一段」補寫一次(因為不會再遇到新字元觸發結算)。

所有變數

  • all:寫入位置(壓縮後結果寫回 chars[all],寫完就 all++
  • count:目前這一段連續出現的次數
  • now:目前正在統計的字元(上一段的代表字元)
  • i:掃描原始 chars 的索引
  • s:把 count 轉成字串後的結果(例如 12 -> "12"),用來逐字寫入

🪜 主要流程步驟

1. 掃描 chars,偵測「段落」的切換

  • 我從左到右掃描 chars[i]
  • 如果 chars[i] != now,代表:
    • 上一段結束
    • 新的一段開始

2. 當遇到新字元時:先結算上一段,再開始新段

now != chars[i] 時,我做兩件事:

(1) 結算上一段(若 count > 1 才寫數字)
  • countto_string(count) 變成字串
  • for (char c : s) 逐字把 '1''2' ... 寫回 chars

for (char c : s) 的意思:把字串 s 裡的每個字元依序取出來,放到變數 c。例如 s = "12",迴圈會跑兩次:c='1'c='2'

(2) 開始新段
  • 更新 now = chars[i]
  • 把這個字元先寫回 chars[all]
  • count = 1(新段剛開始)

3. 當遇到相同字元:只累加次數

  • 如果 chars[i] == now
  • 代表還在同一段
  • 我就 count++

4. 迴圈結束後:補寫最後一段的次數

因為最後一段不會再遇到「新字元」來觸發結算,所以要補做一次:

  • count > 1,同樣把次數轉成字串,逐字寫回

5. 回傳壓縮後長度

  • all 代表壓縮後寫了多少個字元
  • 所以直接回傳 all

💻 程式碼實作

class Solution {
public:
    int compress(vector<char>& chars) {
        int all = 0, count = 0;
        char now = ' ';
        for (int i = 0; i < chars.size(); i++) {
            if (now != chars[i]) {
                if (count > 1) {
                    string s = to_string(count);
                    for (char c : s) {
                        chars[all++] = c;
                    }
                }
                now = chars[i];
                chars[all++] = now;
                count = 1;
            } else {
                count++;
            }
        }
        if (count > 1) {
            string s = to_string(count);
            for (char c : s) {
                chars[all++] = c;
            }
        }
        return all;
    }
};

https://leetcode.com/problems/string-compression/

作者: scottnick
撰寫日期: 2026-01-28
類別:
原文連結: https://scottnick.github.io/cpp-notes/all%20problems/443-string-compression.html