剑指 Offer 46. 把数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”, “mcfi"和"mzi”
来源:力扣(LeetCode)
链接:点击跳转https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof
方法一:递归(树型结构)
- 终止条件:若index走到最后一位,则返回
- 递归条件:若前后两个数符合再10-25区间内,则result结果+1,走左路递归index+2,若前后连个数不符合此区间,则走右路递归index+1
Stack<Integer> stack = new Stack<>(); //存储num的每一位数
int result = 0; //结果
//主函数:返回有result种不同的翻译方法
public int translateNum(int num) {
int[] arr = change(num);
int index = 0;
search(arr,index);
return result+1; //最后加上一种每位数都翻译的情况
}
//树形结构递归每一位
public void search(int[] arr,int index) {
//如果最后剩下一位数,则说明数组遍历完了,返回
if(index > arr.length-2) return;
//如果是10-25之间的数字,则可以发生两位数合在一起翻译
if(arr[index] == 1 || arr[index] == 2 && arr[index+1] < 6) {
result++;
search(arr,index+2); //对应的index下标得往后走两位
}
search(arr,index+1); //index下标往后走一位
}
//将数字转换位数组并返回
public int[] change(int num) {
//从后往前将每一位数放在栈中
while(num > 0) {
stack.push(num%10);
num = num/10;
}
int[] arr = new int[stack.size()];
//数组从头每个元素为栈顶弹出元素
for(int i = 0; i < arr.length; i++) {
arr[i] = stack.pop();
}
return arr;
}
方法二:动态规划
//动态规划
public int translateNum(int num) {
String s = String.valueOf(num);
int a = 1, b = 1;
for(int i = 2; i <= s.length(); i++) {
String tmp = s.substring(i - 2, i);
int c = tmp.compareTo("10") >= 0 && tmp.compareTo("25") <= 0 ? a + b : a;
b = a;
a = c;
}
return a;
}