剑指offer-面试题46:把数字翻译成字符串

题目描述

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”,
“mcfi"和"mzi”
提示:
0 <= num < 2^31

方法一(递归)

1.解题思路
  • 递归终止条件:num只有1位的时候
  • 从上一层递归获取什么:当num最后两位组成的数在10到25之间时,当前层为前两层之和;当num最后两位组成的数不在10到25之间时,当前层等于前一层。
  • 每一层返回什么:返回当前层的方案数

有点类似“爬楼梯”这道题。

2.代码实现
class Solution {
    public int translateNum(int num) {
        if(num>=0&&num<=9) return 1;
        int mod=num%100;
        if(mod>=10&&mod<=25){
            return translateNum(num/10)+translateNum(num/100);
        }
        else{
            return translateNum(num/10);
        }
        
    }
}
3.复杂度分析
  • 时间复杂度:假设n为数字总共有多少位,则时间复杂度为O(n)。
  • 空间复杂度:递归栈的深度为数字的位数,所以空间复杂度为O(n)。

方法二(动态规划)

1.解题思路

思路与递归一模一样,不过采用空间换时间的思路,将之前的状态记录下来。实现上可以先把数字转化为字符串,然后再进行遍历。

2.代码实现
class Solution {
    public int translateNum(int num) {
        String s=String.valueOf(num);
        int n=s.length();
        int[] dp=new int[n+1];
        dp[0]=1;
        dp[1]=1;
        for(int i=2;i<=n;i++){
            int tmp=Integer.parseInt(s.substring(i-2,i));
            if(tmp>=10&&tmp<=25){
                dp[i]=dp[i-1]+dp[i-2];
            }
            else{
                dp[i]=dp[i-1];
            }          
        }
        return dp[n];
    }
}
3.复杂度分析
  • 时间复杂度:假设n为数字总共有多少位,则时间复杂度为O(n)。
  • 空间复杂度:需要长度为n+1的dp数组以及长度为n的字符串,所以空间复杂度为O(n)。

方法三(空间优化)

1.解题思路

可以用两个变量来存储前两层的状态,根据当前余数来跟新当前层与前两层的状态,每次循环将数字最末尾的数抹去。

2.代码实现
class Solution {
    public int translateNum(int num) {
        int a=1,b=1,c=1;
        while(num>0){
            int mod=num%100;
            if(mod>=10&&mod<=25){
                c=a+b;
            }
            else{
                c=b;
            }
            a=b;
            b=c;
            num/=10;
        }
        return c;
    }
}
3.复杂度分析
  • 时间复杂度:假设n为数字总共有多少位,则时间复杂度为O(n)。
  • 空间复杂度:需要额外常数级别的内存空间,所以空间复杂度为O(1)。

剑指offer全集入口: 请戳这里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值