338. Counting Bits
description
Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n), ans[i] is the number of 1’s in the binary representation of i.
Example 1:
Input: n = 2
Output: [0,1,1]
Explanation:
0 --> 0
1 --> 1
2 --> 10
Example 2:
Input: n = 5
Output: [0,1,1,2,1,2]
Explanation:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
answer
solution 1
Brian Kernighan 算法
最直观的做法是对从 00 到 nn 的每个整数直接计算「一比特数」。每个 int 型的数都可以用 32 位二进制数表示,只要遍历其二进制表示的每一位即可得到 1 的数目。
利用 Brian Kernighan 算法,可以在一定程度上进一步提升计算速度。Brian Kernighan 算法的原理是:对于任意整数 x,令 x=x & (x−1),该运算将 x 的二进制表示的最后一个 1 变成 0。因此,对 xx 重复该操作,直到 x 变成 0,则操作次数即为 x 的「一比特数」。
对于给定的 n,计算从 0 到 n 的每个整数的「一比特数」的时间都不会超过 O(logn),因此总时间复杂度为 O(nlogn)。
class Solution {
public int[] countBits(int n) {
int[] bits = new int[n + 1];
for (int i = 0; i <= n; i++) {
bits[i] = countOnes(i);
}
return bits;
}
public int countOnes(int x) {
int ones = 0;
while (x > 0) {
x &= (x - 1);
ones++;
}
return ones;
}
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/counting-bits/solution/bi-te-wei-ji-shu-by-leetcode-solution-0t1i/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个solution中要掌握的就是这个Brian Kernighan 算法。
Brian Kernighan算法可以用于清除二进制数中最右侧的1。
Brian Kernighan算法的做法是先将当前数减一,然后在与当前数进行按位与运算。
x=x&(x-1)
举个例子,20的二进制表示为10100,其最右侧的1在第三位上。20-1=19,19的二进制表示为10011,10100&10011=10000。可以看到,Brian Kernighan算法可以二进制数将最右侧的1清除。
版权声明:本文为CSDN博主「AndyFlyingZZZ」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Andy123321aa/article/details/108182267
1.说白了 Brian kernighan算法就是将一个数的二进制表示的最右边的1去掉。
(用什么方式:x与x-1异或的方式)
2.因为其能够将最右边的1去掉,把一个个1去掉之后就变成0啦,所以就while循环,看在变成0
之前去了多少个1,就说明这个数原本有多少个1.