[剑指-Offer] 46. 把数字翻译成字符串(思维、递归、巧妙解法)

1. 题目来源

链接:把数字翻译成字符串
来源:LeetCode——《剑指-Offer》专项

2. 题目说明

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

示例 1:

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

提示:

  • 0 <= num < 2^31

3. 题目解析

方法一:思维+递归+巧妙解法

题意很明确,求方法总数,以下几点为主要思路:

  • 以 12258 为例,观察数字 1 可发现它能翻译构成两种情况
    • 第一种:单独翻译构成字符 'b',后面剩下数字 2258
    • 第二种:与下一位数字 2 进行有效结合构成字符 ‘m’,后面剩下数字 258
  • 不难发现,从后往前的进行处理,可以写成递归函数的形式。即定义 f ( i ) = f ( i + 1 ) + g ( i , i + 1 ) × f ( i + 2 ) f(i)=f(i+1)+g(i,i+1)\times f(i+2) ,其中 f ( i ) f(i) 表示从第 i i 位数字开始的翻译数目的总和。当第 i i 位与第 i + 1 i+1 位两位拼接翻译起来的数字在范围 10~25 之间时, g ( i , i + 1 ) g(i,i+1) 值为 1 ,否则为 0。

大致梳理程序设计思路:

  • 首先需要将数字 num 采用 to_string 的形式转化为字符串,便于对每一位进行处理
  • 申请一个动态数组,长度等于数字位数,用于记录 f ( i ) f(i)
  • f ( 0 ) = 1 f(0)=1 ,即原数字就为最初始的一种情况
  • 若当前位数字不能有效结合下一位数字构成新情况时,此时情况总数不变,即 f ( i ) = f ( i + 1 ) f(i)=f(i+1)
  • 若当前位与下一位进行有效结合,那么相当于字符串第 i 位与第 i+1 位构成了一个字符替代了第 i+1 位的字符,也就是作为第 i+2 位数字及其以后所有数字的 新头,那么就需要添加 f ( i + 2 ) f(i+2) 的所有情况,这也是递归、迭代的核心思想,数字的结合仅影响该数字后面的所有数字的情况,这个需要理解

上面就是很直观的递归思路,但是这个递归是 自上而下 进行处理的,会产生中间大量的重复运算。将其修改为 自下而上 的迭代解法,从后向前进行处理,可大大提高效率。

其实能够发现这个递归式子很类似于跳台阶问题,也可以从这个方面进行思考!

参见代码如下:

// 执行用时 :0 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :8.3 MB, 在所有 C++ 提交中击败了100.00%的用户

class Solution {
public:
    int translateNum(int num) {
        string tmp = to_string(num);
        vector<int> counts(tmp.size(), 0);
        int count = 0;
        for (int i = tmp.size() - 1; i >= 0; --i) {
            count = 0;
            if (i < tmp.size() - 1) count = counts[i + 1];
            else count = 1;

            if (i < tmp.size() - 1) {
                int cnt = (tmp[i] - '0') * 10 + tmp[i + 1] - '0';
                if (cnt >= 10 and cnt <= 25) {
                    if (i < tmp.size() - 2) count += counts[i + 2];
                    else count += 1;
                }
            }
            counts[i] = count;
        }
        return counts[0];

    }
};
发布了332 篇原创文章 · 获赞 167 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/yl_puyu/article/details/104716621
今日推荐