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中的赋值运算符:重点是取模,取整除,幂赋值运算符
LeetCode_2:每日一题之面试题46.把数字翻译成字符串_第1张图片

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

二、开始做题

注:以下程序皆取个人所见最优,谨慎使用。
方式一: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两个变量来记录他俩的变化,两个变量交替前进即可(两个变量的滚动数组)

LeetCode_2:每日一题之面试题46.把数字翻译成字符串_第2张图片

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

LeetCode_2:每日一题之面试题46.把数字翻译成字符串_第3张图片

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

你可能感兴趣的:(LeetCode,把数字翻译成字符串,字符串,c++,动态规划,算法)