剑指 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、思路

🎃 动态规划

本题类似于,青蛙跳台阶有多少种跳法。

动态规划四大步骤:

穷举分析

对于12258:

1→b;1种;

12→bc,m;2种;

122→bcc,mc,bw;3种;

1225→bccf,mcf,bwf,mz,bcz;5种;

12258→bccfi,mcfi,bwfi,mzi,bczi;5种;

分析找规律,拆分子问题

我们先定义dp[i]为一个有i位的数字能够翻译成字符的个数。

通过穷举分析,我们发现:“1225”就是在“122"基础上加f,有3种;并且刚好5,也就是f,能够和122的末尾的2形成翻译,把2和5组成25后,能够组成“12”能够翻译成的字符个数,有2种;那么”1225“共有5种。

对于”12258“,我们发现在”1225“的基础上加i,有5种;但是末尾的8和前面”1225“的5无法组成翻译,有0种;因此”12258“共5种。

最简单的边界情况

dp[1] = 1;也就是只有一位数字,只有一种情况。

状态转移方程

当前num后面两位能够组成翻译:dp[i] = dp[i-1] + dp[i-2];

当前num后面两位不能组成翻译:dp[i] = dp[i-1];

现在看来完全类似青蛙跳台阶!

2、代码实现

🎃 动态规划

注意一点:“09”和“9”不一样!“09”无法翻译成一个字符。

好理解的

class Solution {
public:
    int translateNum(int num) {
        int last_last_dp = 1;// dp[i-2],初始化为dp[0]=1
        int last_dp = 1;// dp[i-1],初始化为dp[1]=1
        int dp = 1;// num只有一位,不进循环
 
        string str = to_string(num);
        for(int i = 2; i <= str.size(); i++)
        {
            string temp = str.substr(i-2, 2);
            if(temp > "25" || temp < "10")
            {
                dp = last_dp;
            }
            else
            {
                dp = last_dp + last_last_dp;// 要启动循环,必须使last_last_dp初始化为1。比如num等于25时进入此处,last_dp等于1(即dp[1]),此时的最后两个字符即25,在范围内,需要求dp[i-1]=dp[0],等于多少呢?前面没有字符,不变,只有25一种可能,所以是1
            }
            last_last_dp = last_dp;
            last_dp = dp;
        }
        return dp;
    }
};

自己写的 

class Solution {
public:
    int translateNum(int num) {
        int last_last_dp = 1;// dp[i-2]
        int last_dp = 1;// dp[i-1]
        int dp = 1;// dp[i]初始化为dp[1]

        string str = to_string(num);
        for(int i = 2; i <= str.size(); i++)
        {
            if(str[i-1-1]=='1' || (str[i-1-1]=='2' && str[i-1]<'6'))
            {
                dp = last_dp + last_last_dp;
            }
            else
            {
                dp = last_dp;
            }
            last_last_dp = last_dp;
            last_dp = dp;
        }
        return dp;
    }
};

3、复杂度分析

🎃 动态规划

时间复杂度:循环的次数是 n 的位数,故渐进时间复杂度为 O(logn)。

空间复杂度:这里用了一个临时变量把数字转化成了字符串,故渐进空间复杂度也是 O(logn)。

4、运行结果

🎃 动态规划

好理解 

 自己写的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kashine

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值