Brian Kernighan 演算法利用位元運算特性:n & (n - 1) 會清除 n 二進制表示中 最低位的 1。重複執行直到 n == 0,迴圈次數即為 1 的個數。
n = 14 (1110₂)
14 & 13 = 12 (1100₂) → count=112 & 11 = 8 (1000₂) → count=28 & 7 = 0 → count=3結果:3 個 1。迴圈次數等於 1 的個數,而非位寬,對稀疏 1 極其高效。
package algorithm;
public class BitCount {
public static void main(String[] args) {
int[] test = {0, 1, 7, 14, 255, 1024, Integer.MAX_VALUE};
for (int n : test) {
System.out.printf("%d (0x%X) -> %d ones%n", n, n, countOnes(n));
}
}
/**
* 計算整數二進制中 1 的個數
* 時間複雜度:O(k),k = 1 的個數
* 空間複雜度:O(1)
*/
public static int countOnes(int n) {
int count = 0;
while (n != 0) {
n &= (n - 1);
count++;
}
return count;
}
}
| 方法 | 時間複雜度 | 備註 |
|---|---|---|
| Brian Kernighan | O(k) | k=1的個數,稀疏時極快 |
| 查表法 (8-bit/16-bit) | O(1) | 需額外空間,適合極高頻呼叫 |
| Integer.bitCount() | O(1) 硬體指令 | JDK 內建,實際為 POPCNT 指令或優化查表,**生產環境首選** |
| 逐位位移檢查 | O(32) | 固定 32 次迴圈,較慢 |