[LeetCode](面试题46)把数字翻译成字符串

题目

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

示例 1:

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

提示:

0 <= num < 2^31

解题思路

定义递归函数f(i)表示从第i位数字开始的不同翻译的数目,那么

f(i)=f(i+1)+g(i,i+1)*f(i+2),其中当第i位数字和第i+1位数字拼接起来的两位数在[10,25]范围内时,g(i,i+1)=1,否则g(i,i+1)=0。

但自上向下的递归做法求解时会存在重复的子问题,于是我们可以采取自下而上的做法,先求解最小的子问题,从而消除递归时重复的子问题。
定义一个长度为n的dp数组,dp[i]表示第i个数字开始的不同翻译数目,我们最终要求的是dp[0],所以我们从后往前遍历,初始时先令dp[n-1]=1。
1)当i=n-2时,若第i,i+1两位数拼接起来的两位数在[10,25]范围内时,dp[i]=dp[i+1]+1;否则,dp[i]=dp[i+1]。
2)当0<=i<n-2时,若第i,i+1两位数拼接起来的两位数在[10,25]范围内时,dp[i]=dp[i+1]+dp[i+2];否则,dp[i]=dp[i+1]。
3)最后返回dp[0]即可。

代码

class Solution {
    public int translateNum(int num) {
        String s = String.valueOf(num);
        char[] nums = s.toCharArray();
        int n = nums.length;
        int[] dp = new int[n];
        dp[n-1] = 1;
        for(int i=n-2; i>=0; i--){
            int index1 = nums[i]-'0';
            int index2 = nums[i+1] - '0';
            int digit = index1*10 + index2;
            if(10<=digit && digit<=25){
                if(i==n-2){
                    dp[i]=dp[i+1]+1;
                }else{
                    dp[i]=dp[i+1]+dp[i+2];
                }
            }else{
                dp[i]=dp[i+1];
            }
        }
        return dp[0];
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章