力扣: 46. 把数字翻译成字符串

108 阅读1分钟

「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战

描述

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。

  • 示例 1:
输入: 12258
输出: 5
解释: 122585种不同的翻译,分别是"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%的用户