「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战」
描述
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
- 示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
- 提示
0 <= num < 231
解析
通过思路一的尝试,发现第二步时,可以直接用动态规划。关于动态规划的dp公式,是通过debug调试出来的。注意以下易错点: 易错点一: 用 ArrayList 记录每一位数时,注意要用list.add(0, remainder);每次插入时从最前面插入。 易错点二: 别忘了 num=0 的场景,该场景下返回 1 。 易错点三: 判断是否可以组合成两位数时,一定要排除十位数是 0 的场景,避免重复计算,比如 102,满足 <=25 的总共有三种:bac(1,0,2)、kc(10,2) 和 bc(1,02) ;其中 bc(1,02) 中有 02 不符合规范,要排除
示例
class Solution {
public int translateNum(int num) {
ArrayList<Integer> list = new ArrayList<>();
while (num != 0) {
int remainder = num % 10;
list.add(0, remainder);//注意:每次add时,都从index=0处插入。
num = num / 10;
}
int size = list.size();
int[] dp = new int[size];
if (size == 0) {//注意别遗漏该场景
return 1;
}
if (size == 1) {
dp[0] = 1;
return dp[0];
}
if (size == 2) {
dp[0] = 1;
int sum = list.get(0) * 10 + list.get(1);
dp[1] = sum <= 25 ? 2 : 1;
return dp[1];
}
dp[0] = 1;
int sum = list.get(0) * 10 + list.get(1);
dp[1] = sum <= 25 ? 2 : 1;
for (int i = 2; i < size; i++) {
int sum1 = list.get(i - 1) * 10 + list.get(i);
//int add = sum1<=25 ? 1: 0;
//dp[i] = dp[i-1]+dp[i-2];
//dp[i] = dp[i-2]+add;
if (sum1 <= 25 && sum1 != list.get(i)) {//注意要排除list.get(i - 1)==0的场景
dp[i] = dp[i - 1] + dp[i - 2];
} else {
dp[i] = dp[i - 1];
}
}
return dp[size - 1];
}
}
运行结果:
执行结果:通过
执行用时:1 ms, 在所有 Java 提交中击败了81.32%的用户
内存消耗:34.2 MB, 在所有 Java 提交中击败了60.11%的用户