什么是「一比特数」?
「一比特数」是指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 算法过程如下:
执行了 2 次 减少1 的操作,最后返回结果 2,就是 5 的 一比特数。
时间复杂度
Brian Kernighan算法 的最坏情况就是二进制形式是全1的整数,比如 15 的二进制形式是1111,1的个数是logN级别,算法执行的次数是1的个数(需要经历1110,1100,1000,0000),所以时间复杂度是 O(logN)。