【发布时间】:2021-09-21 12:38:20
【问题描述】:
以下函数接受元素列表src以及组合长度r。它打印出所有可能的长度为 r 的组合,而不会重复组合中的元素或以不同的顺序(排列)重复组合。
void fn(List<dynamic> src, int r, List<dynamic> tmp) {
for (var i = 0; i < src.length; i++) {
tmp.add(src.removeAt(i));
if (tmp.length == r) print(tmp.toString());
else if (i < src.length) fn(src.sublist(i), r, tmp);
src.insert(i, tmp.removeLast());
}
}
所以,给定 n = [1,2,3,4,5] 和 r = 3,它会打印出来
[1, 2, 3]
[1, 2, 4]
[1, 2, 5]
[1, 3, 4]
[1, 3, 5]
[1, 4, 5]
[2, 3, 4]
[2, 3, 5]
[2, 4, 5]
[3, 4, 5]
您如何用大 O 表示法描述此函数的时间复杂度?显然,src 和 r 的长度都必须考虑在内。如果我没记错的话,打印出所有重复和排列组合的类似函数的时间复杂度将是 O(n^r)。但是在这种情况下是什么?
【问题讨论】:
-
看起来您的代码打印了所有组合,并且打印该组合所需的时间与组合的长度成正比。所以复杂度必须是(组合的长度)*(组合的数量)。
-
一个组合的长度为r,组合的个数为(length(src) choose r)。请参阅Wikipedia: (n choose k) 了解更多信息。