我有一个算法,使用0到2 ^ n之间的所有位来计算集合的powerset:
public static <T> void findPowerSetsBitwise(Set<T> set, Set<Set<T>> results){
T[] arr = (T[]) set.toArray();
int length = arr.length;
for(int i = 0; i < 1<<length; i++){
int k = i;
Set<T> newSubset = new HashSet<T>();
int index = arr.length - 1;
while(k > 0){
if((k & 1) == 1){
newSubset.add(arr[index]);
}
k>>=1;
index --;
}
results.add(newSubset);
}
}
我的问题是:这个算法的运行时间是多少。循环运行2 ^ n次,并且在每次迭代中,while循环运行lg(i)次。所以我认为运行时间是
T(n) = the sum from i=0 to i=2^n of lg(i)
但是我不知道如何进一步简化这一点,我知道这可以在O(2 ^ n)时间(非空间)递归地解决,所以我想知道上面的方法是否比这更好或更差,时间因为它在太空中更好。
答案 0 :(得分:6)
sigma(lg(i)) where i in (1,2^n)
= lg(1) + lg(2) + ... + lg(2^n)
= lg(1*2*...*2^n)
= lg((2^n)!)
> lg(2^2^n)
= 2^n
因此,建议的解决方案在时间复杂度方面是值得的,然后是递归的O(2 ^ n)。
修改强>
确切地说,我们知道每个k
- log(k!)
位于Theta(klogk)
,因此对于k=2^n
,lg((2^n)!)
位于Theta(2^nlog(2^n) = Theta(n*2^n)
{1}}
答案 1 :(得分:2)
不试图求解或模拟,很容易看出这比O(2 ^ n)差,因为这是2 ^ n * $值,其中$ value大于1(对于所有i> 2)随着n的增加而增加,所以它显然不是常数。
答案 2 :(得分:2)
应用Sterling的公式,实际上是O(n * 2 ^ n)。