题目:
给定一个数字,我们按照如下规则把他翻译成字符串:0翻译成a,1翻译成b……11翻译成l,……25翻译成z,一个数有多种翻译方法,可以把一个数里面的数字看作一位,也可以是两位。
思路:
这个题最麻烦的就是有几种不同的组合方式,最后要算总和。存在多个子问题,并且在分析子问题的时候子问题还可能出现重复计算的可能。所以我们把问题分解成无数个子问题就可以用到递归的算法,并且我们遍历数字的时候我们可以从右边向左边遍历,这样可以防止出现重复计算的情况。在递归的的过程中我们要确定递归的规则,我们定义函数f(i)表示从第i位数字开始的不同翻译的数目,那么f(i)=f(i+1)+g(i,i+1)*f(i+2)。
代码实现:
int translateNum(int num) {
int* nums = (int*)malloc(sizeof(int) * 10);
int* dp = (int*)malloc(sizeof(int) * 10);
int numsSize = 0;
while (num > 9) {
nums[numsSize++] = num % 10;
num /= 10;
}
nums[numsSize++] = num;
for (int i = 0; i < numsSize / 2; i++) {
int tmp = nums[i];
nums[i] = nums[numsSize - i - 1];
nums[numsSize - i - 1] = tmp;
}
dp[0] = 1;
dp[1] = (nums[0] * 10 + nums[1] < 26 && nums[0] * 10 + nums[1] > 9) ? dp[0] + 1 : dp[0];
for (int i = 2; i < numsSize; i++) {
dp[i] = (nums[i - 1] * 10 + nums[i] < 26 && nums[i - 1] * 10 + nums[i] > 9) ? dp[i - 2] + dp[i - 1] : dp[i - 1];
}
return dp[numsSize - 1];
}