0
点赞
收藏
分享

微信扫一扫

[[EVD]] - 剑指 Offer 46. 把数字翻译成字符串

余寿 2022-03-30 阅读 38

题目分析:[[EVD]] - 剑指 Offer 46. 把数字翻译成字符串icon-default.png?t=M276https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/

简单描述:

  • 数字对应26个字母下标.计算一个数字有多少种不同的翻译方法。

限制🚫

  • 0 \le num < 2^{31}
  • 只翻译成小写字母

示例:

解题思路:

思路:

  • #动态规划DP
  • dp操作
    • 只有一个决策,是否单独拿当前数字做翻译,使用dp[i]一维数组
    • dp[i]:以num[i]为结尾的数字的翻译方案数量
    • 状态转移方程:⚠️数字>25必须拆
      • dp[i] = dp[i-1] + (if 10< 2数字组合值 <25)dp[i-2];
    • 空间优化的思路
      • 双辅助变量,因为dp[i]只和前两个节点挂钩.

效率:

  • 时间复杂度O(n)
    •  一维DP,空间复杂度O(n)
    •  辅助变量DP,空间复杂度O(1)

代码:

  • 一维DP
class Solution
{
public:
    /*简单dp,加上判断条件即可,可用递归调用简化代码量*/
    int translateNum(int num)
    {
        int dp[32 + 5];
        dp[0] = 1, dp[1] = 1;
        int cnt = to_string(num).size();
        for (int i = 2; i <= cnt; i++)
        {
            int tmp = num / (int)pow(10, cnt - i) % 100;
            dp[i] = dp[i - 1] + (tmp > 25 || tmp < 10 ? 0 : dp[i - 2]);
        }
        return dp[cnt];
    }
};
  • 使用递归
class Solution
{
public:
    /*简单dp,用递归调用简化代码量*/
    int translateNum(int num)
    {
        if (num < 10) //递归终止条件,一位数时只有1种方案
            return 1;
        int tmp = num % 100;
        /*等价于dp[i] = dp[i - 1] + (tmp > 25 || tmp < 10 ? 0 : dp[i - 2]);
*/
        if (tmp > 25 || tmp < 10)
            return translateNum(num / 10);
        return translateNum(num / 10) + translateNum(num / 100);
    }
};
  • 辅助变量DP
class Solution
{
public:
    /*简单dp,从右向左遍历*/
    int translateNum(int num)
    {

        int a = 1 /*无数字 = 1*/, b = 1 /*一位数 = 1*/;
        int x, y = num % 10;
        while (num)
        {
            num /= 10;
            x = num % 10;
            int tmp = 10 * x + y;
            y = x;
            //不能使用该写法,从右向左遍历时,因为a会改变,而b必须拿到a改变前的数值
            // a = (tmp < 10 || tmp > 25) ? a : a + b;
            // swap(a, b);

            int c = (tmp < 10 || tmp > 25) ? a : a + b;
            b = a;
            a = c;
        }
        return a;
    }
};
举报

相关推荐

0 条评论