不使用位移,有没有办法在O(n)时间内计算2 ^ n?
我正在考虑使用memoization的解决方案,因为我将始终从较低的n开始计算。 即
d = dict()
def pwr2(n):
if n == 0:
return 1
if n == 1:
return 2
if n in d:
return d[n]
d[n] = 2 * pwr2(n-1)
return d[n]
但我不太清楚复杂性会是什么。
编辑:我应该补充一点,我使用这个算法的一部分,以比O(n ^ 2)时间更快的速度将二进制转换为十进制。作为我的分而治之算法的一部分,我必须乘以增加2的幂,因此我尝试记忆。
EDIT2:只需在此处发布我的完整算法,以帮助解决混淆问题 pwr2dict = dict()
def karatsuba(x, y):
// use karatsuba's algorithm to multiply x*y
def pwr2(n):
if n == 0:
return 1
if n == 1:
return 2
if n in pwr2dict:
return pwr2dict[n]
pwr2dict[n] = karatsuba(pwr2(n-1),2)
return pwr2dict[n]
def binToDec(b):
if len(b) == 1:
return int(b)
n = int(math.floor(len(b)/2))
top = binToDec(b[:n]) # The top n bits
bottom = binToDec(b[n:]) # The bottom n bits
return bottom + karatsuba(top, pwr2(len(b)-n))
print binToDec("10110") // Prints 22
答案 0 :(得分:2)
我认为你是在思考你的问题。 2^n
只是意味着将自身加倍n
次。因此,从1到n
的简单循环将起到作用: - )
r = 2
for 1 to n do
r = r * 2
end
这是在O(n)
中运行的解决方案,计算2^n
的真正问题是,在现代计算机上,您可以在相当小的n
内点击架构字长,如32,64或128.然后你必须使用一个任意长度的整数,这可能不会给你很多O(n)
时间,但这是一个不同的问题:-)理论上,它可以完成,琐事,在O(n)
。
修改强>
好的,所以如果我理解你的话你有一个很长的二进制字符串,并且你想把它转换成十进制。
我按如下方式实施:
将长度为n
的二进制字符串放入数组s
(可以是位图以节省空间,可以是支持这些字符串的编程语言中的字符串)。反转字符串,使LSB处于索引0(如果不是这种情况)。
e := 1
r := 0
for i := 0 to (n - 1)
if s[i] = 1
r := r + e
end
e := e * 2
end
反转字符串可以在O(n)
中完成,伪代码只有一个从0
到n - 1
的循环,因此O(n)
也是如此。位串反转可以避免在循环中进行简单的算术运算。并非r
必须是任意长度的整数形式。
答案 1 :(得分:0)
你实际上可以在O(1)时间内完成。乘以2本身意味着左移n-1位。或左移1位n。
您的问题可以通过以下方式解决。
long k = 2 << n-1.
要么
long k = 1 << n.
不是很简单吗?
修改强> 我意识到要做到没有位移。你还不需要O(n)时间。可以在O(logn)
中完成private int power(int x, int n) {
if (n == 1)
return x;
if (n % 2 == 0) {
int power = power(x, n / 2);
return power * power;
}
else{
int power = power(x, (n - 1) / 2);
return x * power * power;
}
}
详细了解递归Recursion
答案 2 :(得分:0)
我们可以在Time = T(f(n)) + T(g(n))
中实现它,其中f(n)
是构建二进制数n
二进制数字所需的时间,而g(n)
是转换所需的时间这个数字为十进制。
public BigInteger pow_2 (int n)
{
String binary = "1";
for (int i=0; i<n; i++) binary += "0"; // f(n)
return new BigInteger(binary, 2); // g(n)
}
由于编译器优化,f(n)
将获得T(f(n))
Θ(1)
。
至于代表g(n)
构造函数的BigInteger(value,radix)
,g(n)
基于二进制数字的位数,其中二进制中的2^n
是一个{{1}的数字数字。