把数字翻译成字符串python_把数字翻译成字符串(Python and C++解法)

题目:

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

示例 1:

输入: 12258

输出: 5

解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof

思路:

可使用递归或动态规划解决该问题,它们的区别:

递归是自上而下解决问题,然后等待从下面返回上来的结果;

动态规划是自下而上解决问题,从已知的 base case 出发,存储前面的状态,迭代出最后的结果;

此处使用动态规划解法:

定义状态:以第 i 位结尾的前缀串翻译的方案数。

转移方程思路:假设翻译字符串的第 i 位置:可以单独作为一位来翻译;如果第 i−1 位和第 i位组成的数字在 10 到 25 之间,可以把这两位连起来翻译。可以用 f(i) 表示以第 i 位结尾的前缀串翻译的方案数,然后考虑第 i 位单独翻译和与前一位连接起来再翻译对 f(i)的贡献。单独翻译对 f(i)的贡献为 f(i - 1);如果第 i−1 位存在,并且第 i−1 位和第 i位形成的数字 x满足 10≤x≤25(如00, 01, 02,35, 99无法被翻译),那么就可以把第 i−1 位和第 i位连起来一起翻译,对 f(i)的贡献为 f(i - 2),否则为 0。

注意1:

如果只翻译自己,比如 12345,如果 5单独翻译,那么方法数与 1234 是一样的,dp(i)=dp(i−1)。

注意2:

由于当前 dp 项只和它前面两项有关,无需用数组存储所有的 dp 项,可用变量去存状态值,在迭代中更新变量,这样空间复杂度优化到 O(1),在C++解法中采用这种做法。另外,由于翻译的对称性,且C++中string的只能取从第i位开始向后的子串,所以采用从右向左的翻译顺序。(python解法中为从左向右)

Python解法:

1 classSolution:2 def translateNum(self, num: int) ->int:3 stred = str(num) #数字转字符串方法,str(2) = '2'

4 Len =len(stred)5 dp = [0] * (Len+1) #备忘录,避免重复计算

6 dp[0] = 1

7 dp[1] = 1

8 for i in range(2, Len+1): #从左到右翻译

9 temp = int(stred[i-2] + stred[i-1]) #字符串转数字方法,int('2') = 2

10 if temp >= 10 and temp <= 25:11 dp[i] = dp[i-1] + dp[i-2]12 else:13 dp[i] = dp[i-1]14 return dp[Len]

C++解法:

1 classSolution {2 public:3 int translateNum(intnum) {4 string stred = to_string(num); //C++数字转字符串方法

5 int prepredpi = 1, predpi = 1, dpi;6 if(stred.size() == 1)7 return 1;8 for(int i = stred.size()-2; i >= 0; i--) { //从右向左翻译

9 string preSubstr = stred.substr(i, 2); //抽取从i位置开始向后的2个字符的子串

10 if(preSubstr >= "10" && preSubstr <= "25")11 dpi = predpi +prepredpi;12 else

13 dpi =predpi;14 prepredpi =predpi;15 predpi =dpi;16 }17 returndpi;18 }19 };

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值