[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];
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章