我在准备面试时发现了以下问题:
3可以写成1+1+1、1+2、2+1;4可以写成1+1+1+1、1+1+2、2+2、1+2+1、2+1+1、3+1、1+3;给定一个整数,存在多少个可能的表达式?(1+2和2+1不同)
因此,编写一个蛮力算法来计算它并获得所有执行它的数字集的集合是相当简单的:
private static Set<List<Integer>> getIntegersSum(int num) {
Set<List<Integer>> returnSet = new HashSet<List<Integer>>();
if (num == 0) {
returnSet.add(new LinkedList<Integer>());
return returnSet;
}
for (int i = 1; i <= num; i++) {
Set<List<Integer>> listNMinI = getIntegersSum(num - i);
for (List<Integer> l : listNMinI) {
l.add(0, i);
returnSet.add(l);
}
}
return returnSet;
}
现在我相信描述这个算法复杂性的递归关系是:
T(0) = \Theta (1)
T(n) = O(n) + \Sum_{i=0}^{n-1} T(i)
我不太确定如何从这种递归关系中得出很大的复杂性。我还想知道这个问题是否有一个封闭形式的解决方案(每个数字我们会有多少这样的组合)。
我也不确定如果我们通过缓存每个调用的结果来记忆这个算法(类似于如何加速斐波那契),那么复杂性会是多少。