我最近偶然发现了一个很好的问题,即使在很长一段时间后似乎无法找出复发关系。
以下是问题陈述:
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.
例如:
if the given input is 121 we can have three encodings
1. ABA (1-->A, 2-->B)
2. LA (12 -->L, 1-->A)
3. AU (1--A, 21--U)
All I was able to achieve was the base cases:
if len(S) == 1:
if S == "0":
return 0
return 1
if len(S) == 2:
if int(S) > 26:
return 1
return 2
除了基本情况,我似乎无法弄清复发关系。任何帮助将不胜感激。感谢。
答案 0 :(得分:0)
假设我们当前位于数字i
数组中的索引a[n]
。右边的位数(包括当前位数)为n - i
。以下是我们需要检查的案例:
n - i <= 0
然后返回1(因为只有一种方法可以排列零位数)。n - i > 1
:
a[i]
和a[i + 1]
给出[10, 26]
范围内的数字,请添加从i + 2
开始的组合数(即我们使用这两位数字)。n - i = 1
或两个超出范围的数字,因此请添加从i + 1
开始的组合数(即消耗一位数)。伪代码:
def countCombos(a[n], i):
if i >= n: return 1
two <- 0
if n - i > 1:
if a[i] == 1 || (a[i] == 2 && a[i + 1] <= 6):
two <- countCombos(a, i + 2)
return two + countCombos(a, i + 1)
我会留给你实施备忘录。
答案 1 :(得分:0)
暂时假设s
不包含零;如果是,f(s)=0
。
只有一种方法可以解码长度为1的字符串:f(s)=1
|s|=1
。对于空字符串---即长度为零的字符串---我们设置f(s)=0
。
现在,为了重复,我们从左端开始,如果s[1..2] <= 26
我们有两种解释方式:decode(s[1]), decode(s[2])
或decode(s[1..2])
。否则,如果s[1..2]>26
只有一个选择。
这自然导致以下复发:
count(s)
if |s| <= 1 then
return |s|
else
v = 0
if s[1..2] <= 26:
v = f(s[1:])
return v + f(s[2:])
显然你想在实践中做一些记忆,以避免指数运行时间。
作为旁注,请注意当s
具有任何1<=i<|s|
s[i..i+1] <= 26
的属性时,重现恰好是斐波那契重复(稍微移位)。