面试题46: 把数字翻译成字符串(C++)

题目地址:https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/

题目描述

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

题目示例

示例 1:

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

解题思路

动态规划:此问题可以看作每次选择一个数字或两个数字用来合并成一个字符,求可以合成多少种字符串。dp[i]表示第i个字符的路径数,对i取一个字符时,则一定在0只25内,此时dp[i] = dp[i-1],表示从i-1到i的路径;当对i取两个字符时,只有在0~25以内时,才有dp[i] = dp[i-2],表示从i-2到i的路径;状态转移方程为当num[i]和num[i-1]能合成一个字符时,dp[i]=dp[i-1],否则,dp[i]=dp[i-1]+dp[i-2]

广度优先搜索(BFS):首先确定一个前缀,前缀有两种可能,单个数或者两位数,两位数限与10到25,我们从低位开始,得到数字的两个前缀,一位数前缀直接递归计算,只有在[10,25]范围内的两位数才能作为前缀递归计算。最后,累计两种前缀的所有方法。

程序源码

动态规划

class Solution {
public:
    int translateNum(int num) {
        if(num == 0) return 1;
        string s = to_string(num);
        vector<int> dp(s.size() + 1);
        dp[0] = 1;
        dp[1] = 1;
        for(int i = 1; i < s.size(); i++)
        {
            if(s[i - 1] == '0' || s.substr(i - 1, 2) > "25")
                dp[i + 1] = dp[i];
            else
                dp[i + 1] = dp[i] + dp[i - 1]; 
        }
        return dp[s.size()];
    }
};

BFS

class Solution {
public:
    int translateNum(int num) {
        if(num == 0) return 1;
        int last_one = num % 10;
        int last_two = num % 100;
        int res = translateNum(num / 10);
        if(last_two >= 10 && last_two <= 25)
        {
            res += translateNum(num / 100);
        }
        return res;
    }
};

猜你喜欢

转载自www.cnblogs.com/wzw0625/p/12819593.html