剑指 Offer 46. 把数字翻译成字符串
中等
588
相关企业
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
下面是我自己的思路,这应该算是深度优先搜索了……?
没有对比就没有伤害,我佩服大佬们的思路。
这其实可看作经典的青蛙跳台问题,
可以跳一层,对应:翻译一个数字到字符;
也可以跳两层,对应:(在满足一定条件下)翻译两个数字到字符。
class Solution {
int count;
public int translateNum(int num) {
// 26 letters
count=0;
char[] str = String.valueOf(num).toCharArray();
pro(str,0);
return count;
}
public void pro(char[] str, int index){
if(index==str.length){
count++;
return;
}else if(index>str.length){
return;
}
// case 1: one char
pro(str,index+1);
// case 2: two chars
if(index+1<str.length && isValid(str,index)){
pro(str,index+2);
}
}
public boolean isValid(char[] str, int index){
if(str[index]=='1'){
return true;
}else if(str[index]=='2'){
if(str[index+1]>='0' && str[index+1]<='5'){
return true;
}else{
return false;
}
}
return false;
}
}
下面是参考过大佬们的解题思路后,自己写的动态规划解法
class Solution {
public int translateNum(int num) {
//dp, dp[i], str[..i] #plans
String s = String.valueOf(num);
char[] str=s.toCharArray();
if(str.length==1){return 1;}
int[] dp = new int[str.length];
dp[0]=1;
if( s.substring(0,2).compareTo("10")>=0 && s.substring(0,2).compareTo("25")<=0){
dp[1]=2;
}else{
dp[1]=dp[0];
}
for(int i=2;i<dp.length;i++){
if(s.substring(i-1,i+1).compareTo("10")>=0 && s.substring(i-1,i+1).compareTo("25")<=0){
dp[i]=dp[i-1]+dp[i-2];
}else{
dp[i]=dp[i-1];
}
}
return dp[dp.length-1];
}
}
最后,借鉴一下大佬们的代码
空间压缩后的动态规划,原因是考虑到计算dp[i]时只使用到dp[i-1],dp[i-2]。
上图来自力扣K神。
class Solution {
public int translateNum(int num) {
String s = String.valueOf(num);
int a=1; // pre , dp[0]
int b=1;// pre pre, dp[-1]
for(int i=1;i<s.length();i++){
String temp = s.substring(i-1,i+1);// [i-1,i]
int c = temp.compareTo("10")>=0 && temp.compareTo("25")<=0 ?a+b:a;// a: dp[i-1], b: dp[i-2]
// move forward,preparation for next iteration
b=a;
a=c;
}
return a;
}
}