###### tags: `Leetcode` `medium` `dynamic programming` `python` # 91. Decode Ways ## [題目連結:] https://leetcode.com/problems/decode-ways/ ## 題目: A message containing letters from ```A-Z``` can be **encoded** into numbers using the following mapping: ``` 'A' -> "1" 'B' -> "2" ... 'Z' -> "26" ``` To **decode** an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways). For example, ```"11106"``` can be mapped into: * ```"AAJF"``` with the grouping ```(1 1 10 6)``` * ```"KJF"``` with the grouping ```(11 10 6)``` Note that the grouping ```(1 11 06)``` is invalid because ```"06"``` cannot be mapped into ```'F'``` since ```"6"``` is different from ```"06"```. Given a string s containing only digits, return the **number** of ways to **decode** it. The test cases are generated so that the answer fits in a **32-bit** integer. **Example 1:** ``` Input: s = "12" Output: 2 Explanation: "12" could be decoded as "AB" (1 2) or "L" (12). ``` **Example 2:** ``` Input: s = "226" Output: 3 Explanation: "226" could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6). ``` **Example 3:** ``` Input: s = "06" Output: 0 Explanation: "06" cannot be mapped to "F" because of the leading zero ("6" is different from "06"). ``` ## 解題想法: * 題目為,給一數字,求其可以表示的解碼組合數 * 使用DP: * 定義dp[i]: 前i個數字字元的組合總數,dp[len(s)]即為所求 * init: dp[0]=1 沒有數字,一種組合 * dp[i]=dp[i-1]+dp[i-2] * 相當於上階梯,可以每次上一階or兩階 * case1: 當前數字自己視為一個字母(自己不能為'0')->總組合數與dp[i-1]一樣 * case2: (當前數字自己+前一個數子)視為一個字母->總組合數與dp[i-2]一樣 * 額外注意,因為以0為起始不可構成任何字串,所以要確認前一個數字是否為0 ``` ex: s='226' 22: 可以decode為 2,2->BB or 22->V 在考慮6時: case1: 可以6自己視為字符,所以總數繼承dp[i-1] case2: 可以與前面一數進行組合, 因為 s[i-2](2)!=0 且 s[i-2]+s[i-1]<=26 所以26可以編碼為Z 所以可以繼承dp[i-2] 所以最終dp[i]=dp[i-1]+dp[i-2]=3 ``` ## Python: ``` python= class Solution(object): def numDecodings(self, s): """ :type s: str :rtype: int """ #dp[i]:前i個字元的組合總數 n = len(s) dp = [0]*(n+1) dp[0]=1 for i in range(1,len(dp)): if s[i-1]!='0': dp[i]+=dp[i-1] if i>1 and s[i-2]!='0' and int(s[i-2]+s[i-1])<=26: dp[i]+=dp[i-2] return dp[n] result = Solution() ans = result.numDecodings("226") print(ans) ```