1. 程式人生 > 其它 >力扣 - 劍指 Offer 46. 把數字翻譯成字串

力扣 - 劍指 Offer 46. 把數字翻譯成字串

題目

劍指 Offer 46. 把數字翻譯成字串

思路1(遞迴,自頂向下)

  • 這題和青蛙跳臺階很類似,青蛙跳臺階說的是青蛙每次可以跳一層或者兩層,跳到第 n 層有多少種解法,而這題說的是講數字翻譯成字串,每次可以翻譯一個或者兩個,但是翻譯兩個的時候還要判斷是否為有效的,像 01、02 這種的數字就是無效的,同時超過 25 也是無效的,因此這些不能被翻譯。然後我們可以得出狀態轉移方程:

    \[dp[i] = \begin{cases} dp[i-1]+dp[i-2] & ,前兩個數字組成的結果在10~25之間 \\ dp[i-1] & ,前面兩個數字組成的結果是0開頭的 \end{cases} \]

程式碼

class Solution {
    public int translateNum(int num) {
        if (num < 10) {
            return 1;
        }

        if (num % 100 >= 10 && num % 100 <= 25) {
            return translateNum(num/10) + translateNum(num/100);
        } else {
            return translateNum(num/10);
        }
    }
}

複雜度分析

  • 時間複雜度:\(O(2^N)\),因為計算過的還是會被遞迴重複計算的,因此時間複雜度為\(O(2^N)\)
  • 空間複雜度:\(O(N)\)

思路2(動態規劃)

  • 因為遞迴時間複雜度比較高,因此我們可以採用動態規劃來解決這題,動態規劃一般都是自底向上,利用 dp 陣列儲存利用之前計算過的資料。狀態轉移方程我們已經知道了,因此可以寫程式碼了

程式碼

class Solution {
    public int translateNum(int num) {
        String str = String.valueOf(num);
        // 使用str.length()+1
        int[] dp = new int[str.length()+1];
        // 我們只能確定第一位有幾種翻譯方法
        // 真正是從 1 開始,初始化 0 是用來來防止 i-2 出現 -1 的情況
        dp[0] = 1;
        dp[1] = 1;

        for (int i = 2; i <= str.length(); i++) {
            // 如果是兩位數的話,需要在10~25之間才有效,否則只能翻譯一個數字
            if (str.substring(i-2, i).compareTo("10") >= 0 && str.substring(i-2, i).compareTo("25") <= 0) {
                dp[i] = dp[i-1] + dp[i-2];
            } else {
                dp[i] = dp[i-1];
            }
        }

        return dp[str.length()];
    }
}

同樣我們可以優化下:

class Solution {
    public int translateNum(int num) {
        String str = String.valueOf(num);
        // 我們只能確定第一位有幾種翻譯方法
        int a = 1;
        int b = 1;

        for (int i = 2; i <= str.length(); i++) {
            // 如果是兩位數的話,需要在10~25之間才有效,否則只能翻譯一個數字
            if (str.substring(i-2, i).compareTo("10") >= 0 && str.substring(i-2, i).compareTo("25") <= 0) {
                int temp = a + b;
                a = b;
                b = temp;
            } else {
                a = b;
            }
        }

        return b;
    }
}

複雜度分析

  • 時間複雜度:\(O(N)\)
  • 空間複雜度:\(O(1)\)
我走得很慢,但我從不後退!