持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情
题目来源:剑指 Offer 46. 把数字翻译成字符串
题目:
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
提示:
0 <= num < 2^31
思路分析:
动态规划:
状态表示:dp[i]表示前i个数字有多少种翻译方法,则dp[n]便表示前n个数字有多少中翻译方法,即结果。
状态转移:
- 当把第i个数字单独翻译成一个字符时,相当于第i个数字已经固定翻译成什么了,则整个数字串有dp[i - 1]种翻译方法
- 当把第i - 2和第i-1个数字合在一起翻译成一个字符时,则整个数字串有dp[i - 2]种翻译方法,但此时应满足第i - 2和第i-1个数字合在一起能翻译成一个字符,即他们两个组成的数字在[10,25]范围内才行。
转移方程:
时间复杂度:
循环的次数是 n 的位数,故渐进时间复杂度为 O(logn)。
空间复杂度:
虽然这里用了滚动数组,动态规划部分的空间代价是 O(1) 的,但是这里用了一个临时变量把数字转化成了字符串,故渐进空间复杂度也是O(logn)。
AC代码:
class Solution {
public:
int getTranslationCount(string s) {
string str=to_string(num);
if(s.empty()) return 0;
int len = s.size();
int dp[len+1];
memset(dp,0,sizeof(dp));
dp[0] = 1;
dp[1] = 1;
for (int i=2;i<=len;i++){
dp[i] = dp[i-1];
int k = s[i-1] - '0';
int k1 = s[i-2] - '0';
if (k1 * 10 + k <= 25 && k1 != 0){
dp[i] += dp[i-2];
}
}
return dp[len];
}
};