Leetcode 91. Decode Ways
A message containing letters from A-Z
is being encoded to numbers using the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message "12"
, it could be decoded as "AB"
(1 2) or "L"
(12).
The number of ways decoding "12"
is 2.
思路: 很显然,由于本题只要求有多少种decode的方法,而不要求吧每种方法都列出来,所以用DP。假设当前的元素为Z,他前面的两个为XY, i.e. XYZ。
1. 如果Z=0, 并且Y=1 or 2。 那么对应于Z的DP值等于X的DP值,因为对于10只有一种解释方式,所以 DP[i] = DP[i-2]。
2. 如果 YZ 位于[11, 19] 或者 [21, 26] 这两个range中,那么显然对于这个两位数我们有两种decode的方式,也就是说 DP[i] = DP[i]+DP[i+2], 注意这里不是DP[i] = DP[i-1]+1。 例如 1212中的最后一个2。
3. 如果X不是0, 例如YZ = 81。 那么DP[i] = DP[i-1].
最后注意的是由于2中我们要取到DP[i-2],所以我们在初始DP list的时候在最前面加上一个1。由于加上了最前面的这个1。所以当DP[i]对应的是s[i-1]。 YZ对应的就是 s[(i-1)-1:(i-1)+1]。
来应对 s = '10' 的corner case。 s[0]='0'的情况也要相应的排除。
1 class Solution(object): 2 def numDecodings(self, s): 3 """ 4 :type s: str 5 :rtype: int 6 """ 7 if not s or s[0]=='0': 8 return 0 9 10 dp = [1,1] 11 12 for i in range(2,len(s)+1): 13 if 21 <= int(s[(i-1)-1:(i-1)+1]) <= 26 or 11 <= int(s[(i-1)-1:(i-1)+1]) <= 19: 14 dp.append(dp[i-1] + dp[i-2]) 15 elif int(s[(i-1)-1:(i-1)+1]) == 10 or int(s[(i-1)-1:(i-1)+1]) == 20: 16 dp.append(dp[i-2]) 17 elif s[i-1] != '0': 18 dp.append(dp[i-1]) 19 else: 20 return 0 21 22 return dp[-1]