剑指offer之二进制位1的个数

2023-11-11 22:09
文章标签 个数 offer 二进制位

本文主要是介绍剑指offer之二进制位1的个数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.求一个整数的二进制表示中有几个1

  • 基础补习:

    左移m<<n,表示m左边n位直接丢弃,同时在右侧补n个0

    右移m>>n,表示右边n位直接丢弃,负数左侧补n个1,正数和无符号数都是左侧补n个0

2.右移解法(错误的)

不断把数字右移1位,和1做&运算,判断最右侧一位是否是1
int NumberOf1(int n)
{int count = 0;while(n){if(n&1)count ++;n = n >> 1; }return n;
}
当输入负数时,右移时,每次左侧补1,死循环

3.左移解法(正确,但不是最优

int NumberOf1(int n)
{int count = 0;unsigned int flag = 1;while(flag){if(n & flag)count ++;flag = flag << 1;}return count;
}
从右往左,依次检测n的每一位是否是1.flag由于是无符号数,当1移到最高位时,仍然有效(flag条件为true),当越过最高位时,flag全部是0,while循环结束。循环次数取决于整数的二进制位数,如果32位整数,那么循环32次

4.更优解法

  • 分析 整数n减去1,如果最后一位是1,那么最后一位设为0

    如果最后一位不是1,从右向左找,找到第一个1,设为0,然后后续位置取反,想想小学的借位减法。

    比如二进制数1100减去1,从右往左找到第一个1(红色那个),再把红色以及后面的位取反,减法后变为1011,然后1100 & 1011 = 1000刚好损失最后一个1

    总结:整数n减去1,找到从右往左第一个位置是1的位,把这个位置以及右侧按位取反

    那么n & (n-1),每次损失最右侧的一个1

  • 代码

    int NumberOf1(n)
    {
    int count = 0;
    while(n)
    {count ++; //能进入while,至少有个位是1n = n & (n-1);//损失最右侧一个1位
    }
    return count;
    }
    

    这个数有个位是1,循环几次

    5.更多应用

  • 一条语句判断一个整数是不是2的整数次方,由于2的整数次方,二进制只有一个位是1,其他位都是0,n&(n-1)之后结果必定为0

  • 两个整数m,n,求m二进制中多少个位于n不同。二进制位不同,想到异或,先求m和n的异或,mn有几个位不同,异或值就有几个位是1,然后数1的个数

这篇关于剑指offer之二进制位1的个数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/393126

相关文章

spoj705( 求不相同的子串个数)

题意:求串s的不同子串的个数 解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstrin

XTU 1233 n个硬币连续m个正面个数(dp)

题面: Coins Problem Description: Duoxida buys a bottle of MaiDong from a vending machine and the machine give her n coins back. She places them in a line randomly showing head face or tail face o

O(n)时间内对[0..n^-1]之间的n个数排序

题目 如何在O(n)时间内,对0到n^2-1之间的n个整数进行排序 思路 把整数转换为n进制再排序,每个数有两位,每位的取值范围是[0..n-1],再进行基数排序 代码 #include <iostream>#include <cmath>using namespace std;int n, radix, length_A, digit = 2;void Print(int *A,

20190315 把整理和培养自己当作一生的事业,而不是局限在找工作拿offer。

把整理和培养自己当作一生的事业,而不是局限在找工作拿offer,做有本事的人。 来东南读研半年了,明显感觉自己掌握的不过是书本知识级别的中上水平,垃圾收集器这些的只知道背面经,靠脑子硬记,缺乏整理和系统,一头浆糊。 现在一边做实训这个烂项目,一边刷面经,一边刷剑指offer,想投些大公司的实习,又觉得还没准备好,看着各 种面经,都能说个大概,但明显感觉到自己知识的不体系和不深入,**做的项目

LCP 485. 最大连续 1 的个数[lleetcode -11]

从今天起,我们的算法开始研究搜索,首先就是DFS深度优先搜索(depth-first seach,DFS)在搜索到一个新的节点时,立即对该新节点进行遍 历;因此遍历需要用先入后出的栈来实现,也可以通过与栈等价的递归来实现。对于树结构而言, 由于总是对新节点调用遍历,因此看起来是向着“深”的方向前进。 下面是一个一维的DFS算法 LCP 485. 最大连续 1 的个数 给定一个二进制数组 nu

双指针(5)_单调性_有效三角形的个数

个人主页:C++忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创 双指针(5)_单调性_有效三角形的个数 收录于专栏【经典算法练习】 本专栏旨在分享学习C++的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. 题目链接: 2.题目描述 : 3.解法 :     解法一(暴力枚举) :     算法思路 :     代码展示 : 暴力枚

HDU2521(求因子个数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2521 解题思路: 数据量不大,直接O(n)遍历,对每个数求其因子个数,找出最大的即可。 完整代码: #include <functional>#include <algorithm>#include <iostream>#include <fstream>#includ

222.完全二叉树的节点个数

(写给未来遗忘的自己) 题目: 代码: class Solution {public:int countNodes(TreeNode* root) {queue<TreeNode*>node_que;if(root==nullptr) return 0;node_que.push(root);int result;while(!node_que.empty()){int layer_s

Kubernetes的alpha.kubernetes.io/nvidia-gpu无法限制GPU个数

问题描述: Pod.yaml文件中关于GPU资源的设置如下: 然而在docker中运行GPU程序时,发现宿主机上的两块GPU都在跑。甚至在yaml文件中删除关于GPU的请求,在docker中都可以运行GPU。 原因: 上例说明alpha.kubernetes.io/nvidia-gpu无效。查看yaml文件,发现该docker开启了特权模式(privileged:ture): 而

编写一个统计空格制表符与换行符个数的函数

int main(int argc, char* argv[]) {  double nc,nc1,nc2;     nc = nc1 = nc2 =0;  int c;  while((c = getchar()) != EOF)  {   if(c == '\t')    nc++;   else if(c == ' ')    nc1++;   else if(c == '\n')