考虑到字母到值的映射,我正试图找到一种方法来确定可以由给定数字拼出的所有可能的单词。
我最终希望找到适用于字母的任何1位或2位数值映射的解决方案,但为了说明,假设A = 1,B = 2,... Z = 26。
示例:12322
可以等于abcbb (1,2,3,2,2)
,lcbb (12,3,2,2)
,awbb (1,23,2,2)
,abcv (1,2,3,22)
,awv (1,23,22)
或lcv (12,3,22)
这是我到目前为止所想到的:
我将使用数字构建一个包含所有可能单词的树。
为此,我将从一棵树开始,其中一个根节点带有虚拟数据。
我将从最低有效数字开始逐位解析数字。
在每一步,我将取数字剩余部分的最后一位数字并将其插入当前节点的左子树,并从该节点的左子树的数字中删除该数字。对于同一节点,我将检查先前的两个数字是否一起形成一个有效的字母表,如果是,我将把它们放入正确的子树(并从该节点的右子树的数字中删除2位数)。
然后,我将使用剩下的数字部分递归地为每个节点重复上述步骤,直到没有剩余数字为止。
为了说明,对于12322
,我的树将看起来像这样:
*
/ \
/ \
2 22
/ / \
2 3 23
/ \ / \ /
3 23 2 12 1
/ \ / /
2 12 1 1
/
1
为了获得单词,我将遍历从叶子到节点的所有可能路径。
对于我认为是一个相当简单的问题,这似乎是一个过于复杂的解决方案,我试图找出是否有一种更简单的方法来解决这个问题。
答案 0 :(得分:5)
您无需实际构建树 - 只需递归:
答案 1 :(得分:2)
假设您已经拥有[2, 3, 2, 2]
的所有可能组合,那么[1, 2, 3, 2, 2]
(将[1]
添加到头部)的组合是什么?推断它应该是不难的:
A1: put [1] to the head of all_the_combinations_of[1,2,3,2,2] and
A2: put [1*10 + 2] to the head of all_the_combinations_of[2,3,2,2] if [1*10 + 2 <=26]
一旦我们得到了这个,以下应该很容易。我实现了一个带有recusion trace的Ruby版本供你参考。
def comb a
c = []
puts a.inspect
return [a] if a.length <= 1
c = comb(a[1..-1]).map {|e| [a[0]] + e}
if a[0] * 10 + a[1] <= 26
c += comb(a[2..-1]).map { |f| [a[0] * 10 + a[1]] + f }
end
c
end
h = Hash[*(1..26).to_a.zip(('A'..'Z').to_a).flatten]
#h.keys.sort.each {|k| puts "#{k}=>#{h[k]}"}
comb([1,2,3,2,2]).each do |comb|
puts comb.map {|k| h[k]}.join
end
[1, 2, 3, 2, 2]
A1 [2, 3, 2, 2]
[3, 2, 2]
[2, 2]
[2]
[]
[2, 2]
[2]
[]
A2 [3, 2, 2]
[2, 2]
[2]
[]
ABCBB
ABCV
AWBB
AWV
LCBB
LCV
答案 2 :(得分:1)
蛮力解决方案是将数组从1动态填充到N,其中a[i]
元素包含一组在扩展后形成a[1]a[2]a[3]...a[i]
的字符串。您可以从stratch填充[1],然后根据a[2]
set和字符串中的第二个字符填充a[1]
。然后你填写[3]等等。在每个场景中,你只需要回顾a[i-1]
和a[i-2]
(以及s[i-1]
和s[i]
,其中{{1}是你的数字序列。)
最后,填写s
后,它将包含答案。
对于示例'12322',序列变为:
a[n]
这实际上是上面递归解决方案的动态编程版本。
答案 3 :(得分:0)
另一种方法是扭转问题: