📌  相关文章
📜  从0到N的整数对的最大设置位计数,得出的总和为N(1)

📅  最后修改于: 2023-12-03 15:06:32.914000             🧑  作者: Mango

从0到N的整数对的最大设置位计数,得出的总和为N

简介

给定一个非负整数 N,找出所有从 0 到 N 的整数对,并计算每对数字的二进制中有多少个设置位。返回这些设置位的总和。例如,给定 N = 3,我们赋值:

  • 0b00 然后计算总和 0。
  • 0b01 然后计算总和 1。
  • 0b10 然后计算总和 1。
  • 0b11 然后计算总和 2。

所以从0到3的整数对的最大设置位计数,得出的总和为2。

实现
算法

我们可以使用位运算,循环从 0 到 N,计算每对数字中设置位的总和。 具体来说,我们可以遍历从 0 到 N,对于每个数字,我们可以使用 Brian Kernighan 的算法计算这个数字中设置位的数量,在相应计数器中增加该数量。 Brian Kernighan 的算法的基本思想是通过使用 $n&n-1$ 删除最低位上的 1,直到所有的 1 均已经被计算。例如,n &= n-1 可以将二进制中最低的一位修改为 0,这样,原始数字中设置位的总数就可以增加 1。

复杂度分析
  • 时间复杂度: $O(N\log N)$,其中 N 是所需计算的最大非负整数。我们需要计算从 0 到 N 中的每个数字。对于每个数字,计算其设置位的数量需要 $O(\log N)$。所以总时间复杂度为 $O(N \log N)$。
  • 空间复杂度: $O(\log N)$, Brian Kernighan 算法仅需要常量空间复杂度,在实现中使用了变量 count 存储正在计算的数字中设置位的总数,所以空间复杂度为 $O(\log N)$。
代码
class Solution:
    def countBits(self, num: int) -> List[int]:
        res = [0] * (num+1)
        for i in range(num+1):
            count = 0
            n = i
            while n != 0:
                count += 1
                n &= n-1
            res[i] = count
        return res