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 ~ 9 的英文單詞[“one”, “two”, “three”, “four”, “five”, “six”, “seven”, “eight”, “nine”] 尋找其中的特徵
- 然後找出單詞出現的次數,由大到小排列輸出出現的數字,這裏的複雜主要是單詞識別的問題,完全識別單詞比較複雜
-
有些字母在單詞中是重複的,貪心思想尋找單詞比較複雜,耐心的尋找單詞中一些特徵
“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)