题目描述
给定一个数字,我们按照如下规则把它翻译成字符串:0翻译成"a",1翻译成"b",。。。,11翻译成"l",。。。,25翻译成"z"。一个数字可能有多个翻译。例如,12258
有5种不同的翻译,分别是bccfi
、bwfi
、bczi
、mcfi
和mzi
。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
思路
这是一个典型的递归问题,我们定义函数 f(i)
表示从第0位数字开始到第i位数字的不同翻译的数目,那么有 f(i) = f(i-1) + g(i-1,i) * f(i-2)
。当第i-1位和第i位两位数字拼起来的两位数在10~25范围内,则g(i-1,i)
为1,否则为0。
尽管用递归的思路来分析这个问题,但由于存在重复的子问题,所以递归的时间复杂度过高。我们选择用空间换时间的方法,将每一步结果存下,避免求解重复子问题。
代码
class Solution {
public:
int getTranslationCount(int number){
if(number < 0)
return 0;
string numberInString = to_string(number);
return getTranslationCount(numberInString);
}
private:
int getTranslationCount(const string &number) {
int len = number.size();
int *counts = new int[len]; // 当前位置的计数
int count = 0;
for (int i = 0; i < len; ++i) {
// 设置初始值
if (i==0)
count = 1;
else
count = counts[i-1];
if (i>0 ){
int digit1 = number[i-1] - '0';
int digit2 = number[i] - '0';
int convertedNum = digit1 * 10 +digit2;
// 该两位数有效
if (convertedNum <= 25 && convertedNum>=10){
if(i>1)
count += counts[i-2];
else
count += 1;
}
}
counts[i] = count;
}
count = counts[len-1];
delete[](counts);
return count;
}
};