比特位计数(二十一)
一、题目描述
这是 LeetCode 上的第三百三十八题:比特位计数,难度为 简单。
Tag:「位运算」
给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。
示例 1:
1 |
|
示例 2:
1 |
|
提示:
1、0 <= n <= 10^5
二、解题思路
最直观的做法是对从 0 到 n 的每个整数直接计算「一比特数」。每个 int 型的数都可以用 32 位二进制数表示,只要遍历其二进制表示的每一位即可得到 1 的数目。
利用 Brian Kernighan 算法,可以在一定程度上进一步提升计算速度。Brian Kernighan 算法的原理是:对于任意整数 x,令 x=x & (x−1),该运算将 x 的二进制表示的最后一个 1 变成 0。因此,对 x 重复该操作,直到 x 变成 0,则操作次数即为 x 的「一比特数」。
对于给定的 n,计算从 0 到 n 的每个整数的「一比特数」的时间都不会超过 O(logn),因此总时间复杂度为 O(nlogn)。
代码实现:
1 |
|
复杂度分析:
1、时间复杂度:O(nlogn)。需要对从 0 到 n 的每个整数使用计算「一比特数」,对于每个整数计算「一比特数」的时间都不会超过 O(logn)。
2、空间复杂度:O(1)。除了返回的数组以外,空间复杂度为常数。
三、总结
本道算法题难度为简单,我们使用了 Brian Kernighan 算法(x &= (x - 1)),它会将我们二进制的最后一个 1 变成 0,因此我们使用一个变量记录这个操作的次数即可
好了,本篇文章到这里就结束了,感谢你的阅读🤝
比特位计数(二十一)
https://sweetying520.github.io/2022/08/25/A21-比特位计数(二十一)/