首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

LeetCode 38 Count and Say:遞歸生成「讀法」序列的兩種 C++ 實現

     編輯:關於C++

題目理解

「報數序列」按規則遞增:

1
11      (1 個 1)
21      (2 個 1)
1211    (1 個 2, 1 個 1)
111221  (1 個 1, 1 個 2, 2 個 1)
...

給定 n(1 ≤ n ≤ 30),返回第 n 項字符串。本質是對上一項進行「行程長度編碼」(RLE)。

迭代法(推薦:清晰、無棧溢出風險)

class Solution {
public:
    string countAndSay(int n) {
        string cur = "1";
        for (int i = 1; i < n; ++i) {
            cur = next(cur);
        }
        return cur;
    }
    
private:
    string next(const string& s) {
        string res;
        int cnt = 1;
        for (int i = 1; i <= s.size(); ++i) {
            if (i < s.size() && s[i] == s[i-1]) {
                ++cnt;
            } else {
                res += to_string(cnt);
                res += s[i-1];
                cnt = 1;
            }
        }
        return res;
    }
};

遞歸法(直觀但深度受限)

class Solution {
public:
    string countAndSay(int n) {
        if (n == 1) return "1";
        string prev = countAndSay(n - 1);
        string res;
        int i = 0;
        while (i < prev.size()) {
            char c = prev[i];
            int j = i;
            while (j < prev.size() && prev[j] == c) ++j;
            res += to_string(j - i);
            res += c;
            i = j;
        }
        return res;
    }
};

關鍵點對比

方面迭代法遞歸法
空間複雜度O(1) 額外空間(不計輸出)O(n) 調用棧
字符串拼接單次遍歷構建結果同
邊界處理循環條件 i <= size() 統一處理最後一組雙指針 i, j 更直觀
性能略快(無函數調用開銷)n≤30 可接受

常見錯誤避坑

  • ❌ 忘記處理最後一組字符(迭代法需 i <= size() 或循環後補充)
  • ❌ cnt + '0' 僅適用於 cnt ≤ 9;n=30 時最大計數可能達 2 位數,**必須用 to_string(cnt)**
  • ❌ 原地修改字符串導致迭代器失效

複雜度分析

  • 序列長度增長約為 1.3 倍/項(Conway 常數),n=30 時長度 ~ 10⁶
  • 時間:O(輸出總長度) ≈ O(1.3ⁿ)
  • 空間:O(最大項長度)

總結

本題核心是實現行程長度編碼(RLE)。迭代法配合 to_string 處理多位數計數是工程首選。理解序列增長規律(Conway 常數)有助於估算空間需求。面試中可先寫遞歸版展示思路,再優化為迭代版體現工程素養。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved