動機
有backtrack的味道,但因為要往前看一格就變成dp
Problem
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 answer is guaranteed to fit in a 32-bit integer.
Example 1:
Input: s = 12Output: 2Explanation: 12 could be decoded as AB (1 2) or L (12).
Example 2:
Input: s = 226Output: 3Explanation: 226 could be decoded as BZ (2 26), VF (22 6), or BBF (2 2 6).
Example 3:
Input: s = 0Output: 0Explanation: There is no character that is mapped to a number starting with 0.The only valid mappings with 0 are 'J' -> 10 and 'T' -> 20, neither of which start with 0.Hence, there are no valid ways to decode this since all digits need to be mapped.
Example 4:
Input: s = 06Output: 0Explanation: 06 cannot be mapped to F because of the leading zero (6 is different from 06).
Constraints:
1 <= s.length <= 100
s
contains only digits and may contain leading zero(s).
Sol
定義dfs(i)是以i為終點的組合數 但我們還需要一個狀態來看前面的數字有沒有被其他2位數用過
class Solution:
def numDecodings(self, s: str) -> int:
@cache
def dfs(i,prev):
if i >= len(s):
return 1
else:
ret = dfs(i+1,True) if 1 <= int(s[i]) < 10 else 0
if prev and i-1 >= 0 and 10 <= int(s[i-1:i+1]) <= 26:
ret += dfs(i+1,False)
return ret
return dfs(0,False)