前往
大廳
主題

LeetCode - 91. Decode Ways 解題心得

Not In My Back Yard | 2022-01-25 00:00:01 | 巴幣 0 | 人氣 602

題目連結:


題目意譯:
一個包含著 A 到 Z 的字母之訊息可以被加密成數字藉由以下的映射:
'A' -> "1"
'B' -> "2"
……
'Z' -> "26"

為了解密一個加密訊息,所有數字必須分組並映射回對應的字母藉由翻轉以上的映射關係(可能會有多種方式解密)。例如,"11106" 可以映射為
"AAJF" 其數字分組為 (1 1 10 6)
"KJF" 其數字分組為 (11 10 6)

注意到數字分組 (1 11 06) 是不合法的,原因是 "06" 不能映射到 'F' 因為 "6" 與 "06" 不同。

給定一個只包含著數字的字串 s,回傳其解密的方法數。

保證答案可以容納近一個 32 位元的整數內。

限制:
1 ≦ s.length ≦ 100
s 只包含數字且可能有著前導零。



範例測資:
範例 1:
輸入: s = "12"
輸出: 2
解釋: "12" 可以被解密為 "AB" (1 2) 或是 "L" (12)。

範例 2:
輸入: s = "226"
輸出: 3
解釋: "226" 可以被解密成 "BZ" (2 26) 、 "VF" (22 6) 或是 "BBF" (2 2 6)。

範例 3:
輸入: s = "0"
輸出: 0
解釋: 沒有字元可以被映射成一個以 0 開頭的數字。
唯一有著 0 的映射為 'J' → "10" 和 'T' → "20",而兩者都不是以 0 開頭。
因此沒有任何可行的方式可以解密,因為所有數字都應要有對應的映射。

範例 4:
輸入: s = "06"
輸出: 0
解釋: "06" 不能映射到 "F" 因為其有著前導零("6" 與 "06" 不同)。


解題思維:
這題的簡化版,可以看到本題的遞迴式就會變得非常地簡單,其為如下:
D[0] = 1,因為什麼都沒有也就不會有解密失敗的問題,因此只有一種解密方式,也就是什麼都沒有;

當 i = 1 時,如果 s[0] 不為 '0' 時,代表只有那一種選擇(即 s[0] 的數字)可以映射。因此 D[1] = 1;反之,如果 s[0] 為 '0' 時,此時沒有任何可行的映射。因此 D[1] = 0。


剩下的 i > 1 之情況,會有以下兩種情況:
一:當 s[i - 1] 不為 '0'(假設其為 X),則又有以下三種子情況:
1. s[i - 2] 為 '2' 且 X ≦ 6 時,代表我們可以產生 "2X"。因此 D[i] = D[i - 1] + D[i - 2];

2. s[i - 1] 為 '1' 時,代表我們可以產生出 "1X"。因此 D[i] = D[i - 1] + D[i - 2];

3. 以上皆非,則代表我們只能單獨地解密當前字元。因此 D[i] = D[i - 1]。

二:當 s[i - 1] 為 '0',則又有以下三種子情況:
1. s[i - 2] 為 '2' 時,代表我們可以結合兩字元產生 "20"。因此 D[i] = D[i - 2];

2. s[i - 1] 為 '1' 時,代表我們可以結合兩字元產生 "10"。因此 D[i] = D[i - 2];

3. 以上皆非,則代表我們既不能解密當前字元也不能與前一字元結合,因此 D[i] = 0。



剩下的就跟先前那題雷同,從 i = 1 跑到 i = s.length 依序求出每個 D[i] 之值即可。而所求為 D[s.length]。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作