⭐算法入门⭐《位运算 - 位与》简单02 —— LeetCode 191. 位1的个数

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了⭐算法入门⭐《位运算 - 位与》简单02 —— LeetCode 191. 位1的个数相关的知识,希望对你有一定的参考价值。

🙉饭不食,水不饮,题必须刷🙉

还不会C语言,和我一起打卡!
🌞《光天化日学C语言》🌞

LeetCode 太难?上简单题!
🧡《C语言入门100例》🧡

LeetCode 太简单?大神盘他!
🌌《夜深人静写算法》🌌

一、题目

1、题目描述

  编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位为 1 的个数。
  样例输入: 00000000000000000000000000001011
  样例输出: 3

2、基础框架

  • c++ 版本给出的基础框架代码如下:
class Solution {
public:
    int hammingWeight(uint32_t n) {
    }
};

3、原题链接

LeetCode 191. 位1的个数

二、解题报告

1、思路分析

  算法思路:我们将一个数末尾二进制的 1 一个一个的消掉(将低位的 1 变成 0),并且每消掉一个 1,计数器就加一,最后计数器的值就是 1 的个数。
  于是,问题就转化成了:如何快速消去二进制末尾的 1。

  • 假设这个数的第 k k k 位为 1,其它 [ 0 , k − 1 ] [0, k-1] [0,k1] 的位置上的值均为 0,则它的表示如下: ? . . . ? 1 00...00 ⏟ k ?...?1\\underbrace{00...00}_{\\rm k} ?...?1k 00...00
  • 那么我们将它减一,得到二进制表示如下(参考二进制减法的借位):
  • ? . . . ? 0 11...11 ⏟ k ?...?0\\underbrace{11...11}_{\\rm k} ?...?0k 11...11
  • 我们将这两个数进行位与,得到了:
  • ? . . . ? 00...00 ⏟ k + 1 ?...?\\underbrace{00...00}_{\\rm k+1} ?...?k+1 00...00
  • 我们发现,通过这个操作,我们就把二进制第 k k k 位的 1 给消去了。利用同样方法,我们继续这样迭代操作,可以把下一个 1 也给消去,直到 n n n 本身等于零为止。
  • 在 C语言中,就是不断进行 n = n & (n-1);的操作。

2、时间复杂度

  • 时间复杂度 O ( C ) O(C) O(C),其中 C C C 是个常数,最坏情况下为 32 32 32

3、代码详解

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int c = 0;
        while(n) {            // (1)
            n &= (n - 1);     // (2)
            ++c;              // (3)
        }
        return c;
    }
};
  • ( 1 ) (1) (1) 循环判断 n n n
  • ( 2 ) (2) (2) n &= (n - 1);等价于n = n & (n - 1);,即消去 n n n 的二进制表示最低位的 1。
  • ( 3 ) (3) (3) 每当消去 1 个 1,就将计数器加一次。
  • 更多有关于位与运算符的作用,可以参考这篇文章:☀️光天化日学C语言☀️(14)- 位运算 & 的应用

三、本题小知识

利用 n &= (n - 1)可以快速消去 n n n 的二进制表示的最右边(低位)的 1。


以上是关于⭐算法入门⭐《位运算 - 位与》简单02 —— LeetCode 191. 位1的个数的主要内容,如果未能解决你的问题,请参考以下文章

数字位运算操作与算法简单示例

&位与运算符|位或运算符之权限控制算法

043Java中逻辑运算之实现位与操作

⭐算法入门⭐《位运算 - 异或》简单01 —— LeetCode 136. 只出现一次的数字

算法——位运算

位运算