从一个数字,我想生成不同的数字组,其中总和对应于这个数字。
示例:
generate_groups([], 1) would be equal to [ [1] ]
generate_groups([], 2) would be equal to [ [1,1] , [2] ]
generate_groups([], 3) would be equal to [ [1, 1, 1], [1, 2], [2, 1], [3] ]
我已经在迭代代码中编写了解决方案,但在递归方面有更好的答案。
所以,我写了下面的代码:
def generate_groups(combo = [], rest)
return combo.flatten if rest <= 0
result = []
(1..rest).each do |number|
combo << number
tmp_res = generate_groups(combo, rest-number)
result << tmp_res
combo.pop
end
return result
end
但它不好,因为它在数组中生成数组。
例如,generate_groups([], 3)
是:
[ [ [ [1, 1, 1] ], [1, 2] ] , [ [2, 1] ] , [3] ]
我的算法出了什么问题?
答案 0 :(得分:2)
您的解决方案可以像这样修复:
def generate_groups(combo = [], rest)
return [combo.dup] if rest <= 0 # no need for flattening
result = []
(1..rest).each do |number|
combo << number
tmp_res = generate_groups(combo, rest-number)
result += tmp_res # concat the solutions instead of nesting them.
combo.pop
end
return result
end
dup
是必要的,否则稍后会通过更改combo
来更改固定结果。您的flatten
也创建了该阵列的副本。
但是,通过递归传递内部状态(combo
)看起来很奇怪。这不是必需的。我的建议
def generate_groups(rest)
return [[]] if rest <= 0
(1..rest).inject([]) do | a, number |
a + generate_groups(rest - number).map { | g | g << number }
end
end
使用inject
,我连接中间结果数组。