一,2的幂
231. 2 的幂 - 力扣(LeetCode)
https://leetcode.cn/problems/power-of-two/?plan=algorithms&plan_progress=gzwnnxs
看题解:
2的幂 - 2 的幂 - 力扣(LeetCode)
https://leetcode.cn/problems/power-of-two/solution/2de-mi-by-leetcode-solution-rny3/
二,位1的个数
191. 位1的个数 - 力扣(LeetCode)
https://leetcode.cn/problems/number-of-1-bits/?plan=algorithms&plan_progress=gzwnnxs
1,循环检查二进制位
思路及解法
我们可以直接循环检查给定整数 n 的二进制位的每一位是否为 1。
具体代码中,当检查第 ii 位时,我们可以让 n 与 2^i进行与运算,当且仅当 n 的第 i 位为 1 时,运算结果不为 0。
class Solution { public: int hammingWeight(uint32_t n) { int ret = 0; for (int i = 0; i < 32; i++) { if (n & (1 << i)) { ret++; } } return ret; } };
复杂度分析
时间复杂度:O(k),其中 k 是 int 型的二进制位数,k=32。我们需要检查 n 的二进制位的每一位,一共需要检查 32 位。
空间复杂度:O(1),我们只需要常数的空间保存若干变量。
2,位运算优化
思路及解法
观察这个运算:n & (n−1),其运算结果恰为把 n 的二进制位中的最低位的 1 变为 0 之后的结果。
这样我们可以利用这个位运算的性质加速我们的检查过程,在实际代码中,我们不断让当前的 n 与 n - 1 做与运算,直到 nn 变为 0 即可。因为每次运算会使得 n 的最低位的 1 被翻转,因此运算次数就等于 n 的二进制位中 1 的个数。
class Solution { public: int hammingWeight(uint32_t n) { int ret = 0; while (n) { n &= n - 1; ret++; } return ret; } };
复杂度分析
时间复杂度:O(logn)。循环次数等于 n 的二进制位中 1 的个数,最坏情况下 n 的二进制位全部为 1。我们需要循环 logn 次。
空间复杂度:O(1),我们只需要常数的空间保存若干变量。