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]

 

posted @ 2017-03-03 00:53  lettuan  阅读(975)  评论(0编辑  收藏  举报