一、Problem
給定一個數字,我們按照如下規則把它翻譯爲字符串:0 翻譯成 “a” ,1 翻譯成 “b”,……,11 翻譯成 “l”,……,25 翻譯成 “z”。一個數字可能有多個翻譯。請編程實現一個函數,用來計算一個數字有多少種不同的翻譯方法。
輸入: 12258
輸出: 5
解釋: 12258有5種不同的翻譯,分別是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
提示:
0 <= num < 231
二、Solution
方法一:dp
- 定義狀態:
- 表示前 個數字可以翻譯成的字符串的方案數。
- 思考初始化:
- ,每一個單獨的數字必定是可以翻譯的。
- 思考狀態轉移方程:難點在這,還是不能快速地找出方程…
- 錯誤版本:如果 ,則有 ;否則
- 思考輸出:
class Solution {
public int translateNum(int num) {
String s = num + "";
int n = s.length(), tot = 0, f[] = new int[n], a[] = new int[n];
for (char c : s.toCharArray())
a[tot++] = c-'0';
Arrays.fill(f, 1);
for (int i = 1; i < n; i++) {
int x = a[i-1] * 10 + a[i];
if (11 <= x && x <= 25) f[i] = f[i] + f[i-1];
else f[i] = f[i-1];
}
return f[n-1];
}
}
- 定義狀態:
- 表示前 個數字可以翻譯成的字符串的方案數。
- 思考初始化:
- ,每一個單獨的數字必定是可以翻譯的。
- 思考狀態轉移方程:難點在這,還是不能快速地找出方程…
- 如果 位置前面的兩個位置可以翻譯成字符串,則有
- 如果 位置前面的兩個位置不能翻譯成字符串,則有
- 思考輸出:
注意狀態表示是前 i 個,所以 dp 數組的大小要開到 n+1
class Solution {
public int translateNum(int num) {
String s = num + "";
int n = s.length(), tot = 0, f[] = new int[n+1], a[] = new int[n];
for (char c : s.toCharArray())
a[tot++] = c-'0';
Arrays.fill(f, 1);
for (int i = 2; i <= n; i++) {
int x = a[i-2] * 10 + a[i-1];
if (x == 10 || 11 <= x && x <= 25)
f[i] = f[i-1] + f[i-2];
else f[i] = f[i-1];
}
return f[n];
}
}
這裏由於爲了方便編碼,我將數字轉爲了字符串,還有將字符串轉化成了整形數組,以及將整個數組都初始化爲了 1,所以效率較低,其實大可不必:
- 字符串轉數字可以優化
- 因爲 dp 的第三個位置只和前兩個位置又連續,所以開始的時候只用初始化 f[0] 和 f[1] 爲 1
複雜度分析
- 時間複雜度:,
- 空間複雜度:,