1. 程式人生 > 其它 >高軟課程總結_SA20225338_羅昊

高軟課程總結_SA20225338_羅昊

首先我們來通過一個例子理解一下這裡「翻譯」的過程:我們來嘗試翻譯「14021402」。

分成兩種情況:

  • 首先我們可以把每一位單獨翻譯,即 [1, 4, 0, 2],翻譯的結果是 beac
  • 然後我們考慮組合某些連續的兩位:
    • [14, 0, 2],翻譯的結果是 oac。
    • [1, 40, 2],這種情況是不合法的,因為 40 不能翻譯成任何字母。
    • [1, 4, 02],這種情況也是不合法的,含有前導零的兩位數不在題目規定的翻譯規則中,那麼 [14, 02] 顯然也是不合法的。

那麼我們可以歸納出翻譯的規則,字串的第 i 位置:

  • 可以單獨作為一位來翻譯
  • 如果第 i−1 位和第 i 位組成的數字在 10 到 25 之間,可以把這兩位連起來翻譯
    到這裡。

我們可以用 \(f(i)\) 表示以第 \(i\) 位結尾的字首串翻譯的方案數,考慮第 \(i\) 位單獨翻譯和與前一位連線起來再翻譯對 \(f(i)\) 的貢獻。單獨翻譯對 \(f(i)\) 的貢獻為 \(f(i−1)\);如果第 \(i−1\) 位存在,並且第 \(i - 1\) 位和第 \(i\) 位形成的數字 \(x\) 滿足 \(10 \leq x \leq 25\),那麼就可以把第 \(i−1\) 位和第 \(i\) 位連起來一起翻譯,對 \(f(i)\) 的貢獻為 \(f(i−2)\),否則為 \(0\)

class Solution {
public:
    int translateNum(int num) {
        string s = to_string(num);
        int n = s.size();
        s = ' ' + s;
        
        vector<int> f(n + 1);
        f[0] = 1;
        for (int i = 1; i <= n; i++) {
            f[i] = f[i - 1];
            if (i >= 2) {
                int x = (s[i - 1] - '0') * 10 + (s[i] - '0');
                if (x >= 10 && x <= 25)
                    f[i] += f[i - 2];
            }
        }
        return f[n];
    }
};