面试题46. 把数字翻译成字符串
难度:中等 2020/6/9每日一题打卡√
题目描述
解题思路
这道题目乍一看很简单的,动态规划,类似那个可以跳一级台阶也能跳两级台阶的问题,dp[i] = dp[i-1] + dp[i-2],信心满满的写完一提交哦豁不对。然后看评论发现有很多特殊情况不能跳两级台阶,比如组成的两位数字大于26 的,没有对应的字母;再比如前一位是0,06这种,也不能跳两级。
例如测试用例:506,就是有一种选择,不能合并50,也不能合并06,搞清楚这点之后就很简单了,实际上就是带有一点限制条件的简单动态规划。
1、动态规划
/*
* 面试题46. 把数字翻译成字符串
* 2020/6/9每日一题打卡√
*/
public int translateNum(int num) {
char[] snum = String.valueOf(num).toCharArray();
int n = snum.length;
int[] dp = new int[n+1];
dp[0] = 1;dp[1] = 1;
for (int i = 2; i < n+1; i++) {
int temp = (snum[i-2] - '0')*10 + snum[i-1] - '0';
if(temp >= 26 || temp < 10) { //如果这个数字大于26,那么只有一种可能的方式
dp[i] = dp[i-1];
}else {
dp[i] = dp[i-2] + dp[i-1];
}
}
return dp[n];
}
上面是先把数字转换成字符数组,也可以用数字分解,用滚动数组来降低空间复杂度
public int translateNum(int num) {
int pre1 = 1,pre2 = 1,p = 0;
while(num > 0) {
int temp = num%100;
num = num/10;
p = pre2;
pre2 = pre1; //滚动数组交换值
if(temp >= 10 && temp < 26) {
pre1 += p;
}
}
return pre2;
}
2、递归法
评论区看到的写法,没有辅助函数
public int translateNum(int num) {
if(num < 10)
return 1;
if(num < 26)
return 2;
if(num < 100)
return 1;
int num2 = num%100;
return translateNum(num / 10) + (num2 < 26 && num2 > 9 ? translateNum(num / 100) : 0);
}