高軟課程總結_SA20225338_羅昊
阿新 • • 發佈:2021-07-18
首先我們來通過一個例子理解一下這裡「翻譯」的過程:我們來嘗試翻譯「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]; } };