「数学」计算正整数的 "一比特数"

550 阅读1分钟

什么是「一比特数」?

「一比特数」是指1正整数二进制表示"1"的数目。

比如5的二进制表示是101,其中1的数目是2,那么5的「一比特数」就是2

如何计算「一比特数」?

直观来说,将正整数转换为二进制表示,然后遍历这个二进制表示,数出1的数目即可。

但是,将正整数转换为二进制表示需要 O(logN) 的时间复杂度 (辗转相除法),然后还要遍历这个二进制表示(一般是用一个字符串),这样的做法不够好。

Brian Kernighan 算法

通过 Brian Kernighan 算法可以提升计算速度,该算法的原理是:

对于任意正整数 n,执行一次 n = n & (n-1) 可以去掉 n的二进制表示 中的最后一个 1

那么,反复执行 n = n & (n-1),直到 n 变为 0执行的次数 就是 n一比特数

5为例,执行 Brian Kernighan 算法过程如下:

BK.png

执行了 2减少1 的操作,最后返回结果 2,就是 5一比特数

时间复杂度

Brian Kernighan算法 的最坏情况就是二进制形式是全1的整数,比如 15 的二进制形式是11111的个数是logN级别,算法执行的次数是1的个数(需要经历1110110010000000),所以时间复杂度O(logN)