leetcode-剑指 Offer 46. 把数字翻译成字符串

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

示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”, “mcfi"和"mzi”

提示:
0 <= num < 231

解题方法:

法一:动态规划

dp[i]代表到当前第i位为止,有多少种翻译方式。翻译方式分为两类:
a.只翻译当前的一位
b.将当前的第i位字符与第I-1位组合起来翻译
比如:316
a. 6可以单独翻译,那么dp[i]=dp[i-1]+1 ,这里不是+1,因为是在31的方法上里的同一种方法,它们是一种翻译方法。
b. 6可以单独翻译,也可以和他的前一位1一起翻译,也就是组成16,
即dp[i]=dp[i-1]+dp[i-2](注意:这里需要判定数字的范围 若数字为356 那么56是不满足一起组合翻译的条件的,所以组合的数字要求是在10-25之间的

class Solution {
public:
    int translateNum(int num) {
    string s=to_string(num);
    int n=s.size();
    vector<int> dp(n+1,0);
    dp[0]=1,dp[1]=1;
    for(int i=2;i<n+1;i++)
    {
    	if(s[i-2]=='1'||(s[i-2]=='2'&&s[i-1]<'6'))
    	dp[i]=dp[i-1]+dp[i-2];
    	else
    	dp[i]=dp[i-1];
    }
    return dp[n]];
    }
  };

法二:迭代
若数字在0-9之间,那么只有一种方法,所以这是递归的出口。
if(num<10) return1;
由于需要特殊判定的10-25可以组成两种方式的翻译方法,要么单一翻译,要么组合在一起翻译:
a. num%100如果在10-25之间,那么就是两种递归情况叠加(num/10)是单独翻译,(num/100)是两位一起翻译。
b. num%100<10或者num%100>25 当前这一位只能自己独自翻译,所以继续迭代前面其余的数字(Num/10)

class Solution {
public:
    int translateNum(int num) {
        if(num<10) return 1;
        if(num%100<10||num%100>25) return translateNum(num/10);
        else return translateNum(num/100)+translateNum(num/10);
    }
};

法三:回溯

class Solution {
    int res=0;
    void dfs(string &s,int start)
    {
         int len=s.size();
         if(start>=len)   //终止条件
         {
             res++;
             return ;
         }
         dfs(s,start+1);   //a情况:独自翻译
         if(start<len-1&&s[start]>='1'&&s[start]<='2')   //b情况
         {
               if(s[start] =='1' || s[start] == '2' &&s[start+1]<'6')
                dfs(s,start+2);
         }
    }
public:
    int translateNum(int num) {
        string s=to_string(num);
        dfs(s,0);
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值