2020/3/17 打卡
題目
一條包含字母 A-Z 的消息通過以下方式進行了編碼: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 給定一個只包含數字的非空字符串,請計算解碼方法的總數。 示例 1: 輸入: "12" 輸出: 2 解釋: 它可以解碼爲 "AB"(1 2)或者 "L"(12)。 示例 2: 輸入: "226" 輸出: 3 解釋: 它可以解碼爲 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。
思路
這道題和爬樓梯的那道題的思路很像,都是最後一種狀態由前兩種狀態轉化而來。(使用動態規劃,使用類似樓梯的方法解決即可) 所以直接使用動態規劃進行情況搜索即可,狀態值表示解碼方法的總數。 1.我們知道最後一個字母有可能是由一個數字串或兩個數字串轉化而來,例如'12312'這個數字串,轉化成字母串最後一位可以是'2'轉成B,也可能是'12'轉成L 2.設數字串S的前i個數字解密成字母串有dp[i]種方式:那麼就有dp[i] = dp[i-1] + dp[i-2] dp[i-1]表示最後一個數字解密成一個字母 dp[i-2]表示最後兩個數字解密成一個字母 3.由於這裏存在很多特殊情況: 例如dp[i-2]表示最後兩個數字解密成一個字母的情況必須要至少有兩個數字 例如最後兩個字母大於26,像55、01等是不存在dp[i-2]這種情況的 所以,像下面的拆開寫狀態轉移方程,分別判斷是很好的思路,見代碼。
代碼
def DP_fun(s):
size=len(s)
# 邊界條件
if size==0:
return 0
#創建 狀態,表示 到當前位置,可以有的解碼方法總數
dp=[0]*(size+1)
# 狀態初始化
dp[0]=1
# 進行狀態轉移操作
for i in range(1,size+1):
#—————————— 接下來對於每個位置,都做了 dp[i] = dp[i-1] + dp[i-2]組合的相加 ——————————————————
t = int(s[i - 1])
# 最後一個數字解密成一個字母。 先加上 前一個包裝成dp[i-1]的情況。
if t >= 1 and t <= 9:
dp[i] += dp[i - 1]
# 下面這種情況至少要有兩個字符。 再加上 前兩個可以包裝成dp[i-2]的情況(需要組合數在 0-26範圍內。)。
if i >= 2:
t = int(s[i - 2]) * 10 + int(s[i - 1])
if t >= 10 and t <= 26:
# 最後兩個數字解密成一個字母
dp[i] += dp[i - 2]
# 最後一個位置上的統計 ,就是整體對整個字符串的 編碼方法總數上的統計。
return dp[-1]