以下是我在访谈街道网站上看到的C ++代码,从0~a(输入数字)计算1位,我们可以说是1~a,因为0没有1。此代码的时间复杂度为使用重复的O(logn)。
我只是不明白逻辑。谁能解释为什么?谢谢!
long long solve(int a)
{
if(a == 0) return 0 ;
if(a % 2 == 0) return solve(a - 1) + __builtin_popcount(a) ;
return ((long long)a + 1) / 2 + 2 * solve(a / 2) ;
}
BTW __builtin_popcount()是GNU提供的内置方法,用于计算1位。
答案 0 :(得分:2)
我会抓住O(lg n)
复杂性。请注意,虽然证明应该仍然保留运行时间,但我不太明白该函数的作用。
考虑到我们的复发关系:
T(a) = 0, if a == 0
| T(a - 1) + O(1), if a is divisible by 2
\ O(1) + T(a/2)
我将在这里使用迭代方法:
T(a) = T(a/2) + O(1)
T(a) = T(a/2^2)) + O(1) + O(1)
T(a) = T(a/2^k)) + (k-1)O(1)
// continue unrolling until we reach the base case
T(a) = 0 + O(1) + ... + O(1) + O(1) = kO(1)
// k here corresponds to lg a since we continued dividing the problem set in half
T(a) = (lg a)*O(1)
T(a) = lg a
Q.E.D。