算法練習每日一題:從英文中重建數字

423. 從英文中重建數字

給定一個非空字符串,其中包含字母順序打亂的英文單詞表示的數字0-9。按升序輸出原始的數字。

注意:

輸入只包含小寫英文字母。

輸入保證合法並可以轉換爲原始的數字,這意味着像 “abc” 或 “zerone” 的輸入是不允許的。

輸入字符串的長度小於 50,000。

  • 示例 1:

輸入: “owoztneoer”

輸出: “012” (zeroonetwo)

  • 示例 2:

輸入: “fviefuro”

輸出: “45” (fourfive)

鏈接:https://leetcode-cn.com/problems/reconstruct-original-digits-from-english

題解分析:

  1. 首先枚舉 1 ~ 9 的英文單詞[“one”, “two”, “three”, “four”, “five”, “six”, “seven”, “eight”, “nine”] 尋找其中的特徵
  2. 然後找出單詞出現的次數,由大到小排列輸出出現的數字,這裏的複雜主要是單詞識別的問題,完全識別單詞比較複雜
  • 有些字母在單詞中是重複的,貪心思想尋找單詞比較複雜,耐心的尋找單詞中一些特徵

    “z” 只在 “zero” 中出現

    “w” 只在 “two” 中出現

    “u” 只在 “four” 中出現

    “x” 只在 “six” 中出現

    “g” 只在 “eight” 中出現

    • 這時候通過識別這一個字母,就代表這個單詞出現了:

      0 = “z”

      2 = “w”

      4 = “u”

      6 = “x”

      8 = “8”

    • 另外:

      “h” 只在 “three” 和 “eight” 中出現

      “f” 只在 “five” 和 “four” 中出現

      “s” 只在 “seven” 和 “six” 中出現

      “i” 在 “nine”,“five”,“six” 和 “eight” 中出現

      “n” 在 “one”,“seven” 和 “nine” 中出現

    • 那麼 3 出現的次數 = "h"的次數 - 8(“g”)的次數;一次類推:

      5 = “f” - “u”

      7 = “s” - “x”

      9 = “i” - “five”-“six” - “eight” = “i” - (“f” - “u”) - “x” - “g”

      1 = “n” - (“i” - (“f” - “u”) - “x” - “g”)*2 - ( “s” - “x”) # nine 中 “n” 有 2 次

如此,只要我們計算出字符串中每個字符出現的數字,就能枚舉出 0 ~ 9 出現的次數;Python3 內置的 collections.Counter(s) 能方便的幫我們統計可迭代列表(字符串)中每個元素出現的次數,返回 dict 對象;相應的我們也以 0 ~ 9 爲鍵,存儲出現的次數,最後使用 sorted 方法以 key 排序輸出。

請參考官方題解,一開始我一直糾結如何完整的識別出單詞,以及題幹給出的 “輸入保證合法並可以轉換爲原始的數字,這意味着像 “abc” 或 “zerone” 的輸入是不允許的。”的用意。

一般在理解題意之後就在考慮如何用代碼模擬數學計算解題;這其中有一些典型的方法和思想:枚舉,遞歸,歸併排序,隨機數快速排序,二分查找,分治法(貪心,動態規劃),還有一些複雜數據結構如二叉樹,圖,集合的特殊算法。題乾的理解一般都是數學的枚舉、歸納推理過程。

class Solution:
    def originalDigits(self, s):
        strCount = collections.Counter(s)
        rst = collections.defaultdict(int)
        rst[0] = strCount["z"]
        rst[2] = strCount["w"]
        rst[4] = strCount["u"]
        rst[6] = strCount["x"]
        rst[8] = strCount["g"]
        rst[3] = strCount["h"] - rst[8]
        rst[5] = strCount["f"] - rst[4]
        rst[7] = strCount["s"] - rst[6]
        rst[9] = strCount["i"] - rst[5] - rst[6] - rst[8]
        # rst[1] = strCount["n"] - (strCount["i"] - (strCount["f"] - strCount["u"]) - strCount["x"] - strCount["g"]) - (strCount["s"] - strCount["x"])
        rst[1] =  strCount["n"] - rst[9] * 2 - rst[7] # 9 nine , "n" 出現 2 次
        
        # 之後排序後輸出,這裏用到了 Python 列表的特性 “a” * 3  = “aaa”
        rst = [str(key)*rst[key] for key in sorted(rst.keys())]
        return "".join(rst)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章