【LeetCode 日記】面試題46. 把數字翻譯成字符串(換皮題)

原題地址: https://leetcode-cn.com/probl...python

題目描述

給定一個數字,咱們按照以下規則把它翻譯爲字符串:0 翻譯成 「a」 ,1 翻譯成 「b」,……,11 翻譯成 「l」,……,25 翻譯成 「z」。一個數字可能有多個翻譯。請編程實現一個函數,用來計算一個數字有多少種不一樣的翻譯方法。git

示例 1:github

輸入: 12258
輸出: 5
解釋: 12258 有 5 種不一樣的翻譯,分別是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"編程

提示:數組

0 <= num < 231函數

思路

咱們另 f(n)表示給定數字 num 的狀況下,從 num 的第 1 位(包含)到第 n 位(包含)有多少種不一樣的翻譯方法。優化

咱們從幾個簡單的例子入手,嘗試打開思路。spa

對於數字 12258 來講:翻譯

| (擋板)表示從這裏分開翻譯, ,(逗號)表示分割多個翻譯方式。
  • f(1) = 1,分別爲 1。
  • f(2) = 2,分別爲 1|2, 12。
  • f(3) = 3,分別爲 1|2|2,1|22,12|2
  • ...

其實對於 f(3) 來講, 我手動的狀況下,是這麼想的:code

  • 先把 f(2) 結果搬過來,即 1|2,12
  • 在 f(2)的基礎上分割,我要添加第三位,也就是一個 2 到末尾。 1|2|2 這樣是行的, 12|2 一樣是能夠的。
  • 繼續在 f(1) 的基礎上分割,我要添加第三位,也就是一個 2 到末尾。 1|22

那麼總的狀況就是三種。OK,總結下個人邏輯:

  • 若是我不能夠和前面的數字組成 10 - 25 之間的數,那麼在 f(n - 1) 的末尾添加擋板
  • 若是能夠,同時在 f(n - 1)和 f(n -2) 的末尾添加擋板

用圖來表示:

所以,實際上這道題就是爬樓梯的換皮題。

代碼

class Solution:
    def translateNum(self, num: int) -> int:
        @lru_cache
        def helper(s: str) -> int:
            if not s: return 1
            pre = helper(s[:-1])
            if 10 <= int(s[-2:]) <= 25:
                return pre + helper(s[:-2])
            return pre
        return helper(str(num))

複雜度分析

  • 時間複雜度:最壞的狀況,每個數組均可以和前面的組成新的數組, 有大約 $2^N$ 種組合,所以時間複雜度爲 $O(2^N)$,而我這裏使用了 @lru_cache 所以不會有重複計算,時間複雜度爲 $(N)$,其中 N 爲 數字長度。
  • 空間複雜度:因爲空間複雜的受遞歸調用棧的影響,所以空間複雜度爲 $O(2^N)$,而我這裏使用了 @lru_cache 所以不會有重複計算,空間複雜度爲 $(N)$,其中 N 爲 數字長度。

若是你願意的話,其實優化起來也比較簡單,咱們只須要 bottom-up 便可。

class Solution:
    def translateNum(self, num: int) -> int:
        s = str(num)
        n = len(s)
        dp = [1] * n
        for i in range(1, n):
            dp[i] = dp[i - 1]
            if 10 <= int(s[i - 1:i + 1]) <= 25:
                dp[i] += dp[i - 2]
        return dp[-1]

進而能夠優化到空間 $O(1)$

class Solution:
    def translateNum(self, num: int) -> int:
        s = str(num)
        n = len(s)
        a = b = 1
        for i in range(1, n):
            if 10 <= int(s[i - 1:i + 1]) <= 25:
                temp = a
                a = b
                b = temp + b
            else:
                a = b
        return b

更多題解能夠訪問個人 LeetCode 題解倉庫:https://github.com/azl3979858... 。 目前已經 30K star 啦。

你們也能夠關注個人公衆號《力扣加加》獲取更多更新鮮的 LeetCode 題解

相關文章
相關標籤/搜索