⭐算法入门⭐《位运算 - 位与》简单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。


  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

英雄哪里出来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值