Vison's Blog
所有文章
文章总览
编辑器
Publications
About Me
Search
目录
#toc-container
下载Markdown文件
【3.22】LeetCode每日一题· 位1的个数
2021年03月22日 8时54分
标签:
LeetCode
二进制
## 题目描述 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为[汉明重量](https://baike.baidu.com/item/%E6%B1%89%E6%98%8E%E9%87%8D%E9%87%8F))。 提示: * 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。 * 在 Java 中,编译器使用[二进制补码](https://baike.baidu.com/item/%E8%A1%A5%E7%A0%81/6854613?fromtitle=%E4%BA%8C%E8%BF%9B%E5%88%B6%E8%A1%A5%E7%A0%81&fromid=5295284)记法来表示有符号整数。因此,在上面的**示例 3**中,输入表示有符号整数`-3`。 #### 示例1 ``` 输入:00000000000000000000000000001011 输出:3 解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。 ``` #### 示例2 ``` 输入:00000000000000000000000010000000 输出:1 解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。 ``` #### 示例3 ``` 输入:11111111111111111111111111111101 输出:31 解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。 ``` #### 提示 ``` 输入必须是长度为 32 的 二进制串 。 ``` #### 来源 > 来源:力扣(LeetCode) > 链接:[题目链接](https://leetcode-cn.com/problems/number-of-1-bits "题目链接") ## 循环右移方法 `n&1`可以判断`n`的最后一位是否是`1`。 因此我们判断`n&1`的值,如果`n&1==1`,则表明当前二进制串中最后一位是1,计数器加一;否则表明最后一位是0。然后将`n`右移一位,判断倒数第二位是否是1。如此循环直到`n==0`为止。 ### 代码 ```cpp class Solution { public: int hammingWeight(uint32_t n) { int cnt = 0; while(n){ if(n&1){ cnt++; } n >>= 1; } return cnt; } }; ``` ### 用时和内存 > 执行用时:0 ms,在所有 C++提交中击败了100.00%的用户 > 内存消耗:5.9 MB,在所有 C++提交中击败了43.04%的用户 ## 位运算优化 考虑`n&(n-1)`,该式能够将`n`最低位的1变为0,因此只需要不断执行`n = n&(n-1)`,每执行一次计数器加一,直到`n`为0为止即可。 ### 代码 ```cpp class Solution { public: int hammingWeight(uint32_t n) { int cnt = 0; while(n){ cnt++; n &= (n-1); } return cnt; } }; ``` ### 用时和内存 > 执行用时:0 ms,在所有 C++提交中击败了100.00%的用户 > 内存消耗:5.9 MB,在所有 C++提交中击败了59.04%的用户 ## 相关题目 这里要求的是**一个数中,二进制位为1的个数**,如果要求连续区间内各个数的二进制位为1的个数,可以采用递推法,见[比特位计数](http://www.vison307.com/23/)。
所有评论
暂无评论
新增评论
评论
邮箱
邮箱仅作验证使用
图形验证码
邮箱验证码
发送验证码
发表评论
所有评论
暂无评论