LeetCode_2:每日一题之面试题46.把数字翻译成字符串

第二天,吼吼~

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

示例 1:

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

来源:力扣(LeetCode)

一、边看边学

概念盲区:
1.递推:递推算法是一种用若干步可重复运算来描述复杂问题的方法。
2.递推与递归的区别:递推的结构为线型,人的简单逻辑推理,一件事想到另一件事。
递归是自我嵌套的稍复杂结构,有个经典的例子: 我梦见自己在做梦。
3.动态规划(dynamic programming,简称DP)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。 [1] 20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。
4.滚动数组是DP中的一种编程思想。简单的理解就是让数组滚动起来,每次都使用固定的几个存储空间,来达到压缩,节省存储空间的作用。起到优化空间,主要应用在递推或动态规划中(如01背包问题)。因为DP题目是一个自底向上的扩展过程,我们常常需要用到的是连续的解,前面的解往往可以舍去。所以用滚动数组优化是很有效的。利用滚动数组的话在N很大的情况下可以达到压缩存储的作用。(摘从作者小白求学进阶)
5.字符串切片的语法
[开始索引:结束索引:步长]
切取字符串为开始索引到结束索引-1内的字符串
步长不指定时步长为1 字符串[开始索引:结束索引]
例子:截取2 - 5位置的字符程序为:
num_str_1 = num_str[2:6]、s[i-2: i]
6.Python中的赋值运算符:重点是取模,取整除,幂赋值运算符
Python赋值运算符

7.a, b = b, a+b 这个表达式的意思就是说,先计算=号的右边b的值,a+b的值,算好了,然后再分别赋值给a 和b就可以了。
8.string src = to_string(num),to_string函数功能是将数值转化为字符串,返回对应的字符串。
9.substr是C++语言函数,主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。
10.C++中比较大小的表达式中,小于号和大于号都是不能连着打的,要用&&连接起来,这一点不同于日常的数学表达式,例如if(a<b<c)或者if(0<a<100)都是不正确的写法。

二、开始做题

注:以下程序皆取个人所见最优,谨慎使用。
方式一:Python采用DP中的动态数组
成绩:44ms/13.6mb
思路:1.将num这个数转换为字符串s,为的是通过字符串遍历实现动态规划。
2.字符串切片s[i-2: i]来代替10Xi-1+Xi,在通过’10’来代表10,通过字符串ASCII码判断字符串数字区间的方式代替 10<=两位数<=25这个语句。
3.因为dp[i]只与dp[i-1]有关,因此采用a、b两个变量来记录他俩的变化,两个变量交替前进即可(两个变量的滚动数组)

方式

class Solution:
    def translateNum(self, num: int) -> int:
        s = str(num)
        a = b = 1
        for i in range(2, len(s)+1):
            a, b = (a+b if '10' <= s[i-2: i] <= '25' else a), a
        
        return a

方式二:C++
成绩:0ms/5.9mb
思路:滚动数组采用三个变量,认为dp[i]与dp[i-1],dp[i-2]有关。编程思路与python类似。。。偷懒了。。

class Solution {
public:
    int translateNum(int num) {
       string src = to_string(num);
        int p = 0, q = 0, r = 1;
        for (int i = 0; i < src.size(); ++i) {
            p = q; 
            q = r; 
            r = 0;
            r += q;
            if (i == 0) {
                continue;
            }
            auto pre = src.substr(i - 1, 2);
            if (pre <= "25" && pre >= "10") {
                r += p;
            }
        }
        return r; 
    }
};

三、核心难点及个人感受

1.核心难点:动态规划(滚动数组),利用递推公式即转移方程求解,典型的用时间换空间,优化空间但是时间较长。核心技术图:

在这里插入图片描述

2.个人感受(读者请注意,以下为个人矫情环节):动态规划第一次接触,真的难,算法真的讲究。都是大佬们的心血,人家教你你还不想学,太不给面子了,一定要一点一点扣会,都是经典。另外,算法懂了,还要有编程思路。基本就是算法+编程思路。我有点忽视编程思路。。。其实是算法对我来说有点难,导致工作量有点大。。。但是必须一天一篇。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值