此问题非常适合递归解决方案。
通常情况下的解决方案是通过采用N - 1
的解决方案,然后将每个设置的元素依次添加到结果中形成的。在伪代码:
f(options, 0) = []
f(options, n) = options foreach o => o ++ f(options, n-1)
这可能递归用Java来实现,但你会遇到堆栈溢出错误为n
中等大值;我也怀疑JIT编译器在优化递归算法方面效率不高,因此性能会受到影响。
但是,递归算法总是可以转换成等效的循环。在这种情况下,它可能看起来像:
List<String> results = new ArrayList<String>();
results.add(""); // Seed it for the base case n=0
for (int i = 0; i < n; i ++) {
List<String> previousResults = results;
results = new ArrayList<String>();
for (String s : options) {
for (String base : previousResults) {
results.add(s + base);
}
}
}
return results;
这种工作方式类似于递归方法 - 在每次迭代它“拯救”目前的进度(即,n-1
的结果)previousResults
,然后(我希望!)只是依次迭代选项,以获得将结果添加到前一结果的结果。
看到通过任何自动递归迭代算法传递递归解决方案的效果,并将可读性和性能与此手工创建的算法进行比较,将会很有趣。这留给读者作为练习。
这是**的变体**,因为顺序是相关的。您的问题与N位数字的K数字一一对应。 – 2012-07-06 11:00:30
我同意@MarkoTopolnik。但是,这几乎是一个常见问题,所以我投票结束。 – 2012-07-06 11:07:02
[重复变异的代码(combinatorics)的可能的重复?](http://stackoverflow.com/questions/2366074/code-for-variations-with-repetition-combinatorics) – 2012-07-06 11:07:59