剑指 Offer 46.! 把数字翻译成字符串(动态规划,青蛙跳台问题的变形)

该文主要讨论如何计算一个数字用特定规则翻译成字符串的不同方法数。首先介绍了深度优先搜索的解法,然后是动态规划的解决方案,最后优化了空间复杂度的动态规划方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

示例 1:

输入: 12258
输出: 5
解释: 122585种不同的翻译,分别是"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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值