剑指offer系列5:二进制中1的个数
Posted neverland0718
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer系列5:二进制中1的个数相关的知识,希望对你有一定的参考价值。
先说下原码,反码和补码的概念。在计算机中用第一位表示数的正负,正数为0,负数为1。所有正数的这三个码相等。对于负数来说,这三个码都不影响其符号位。反码给所有位取反,补码给反码加1。
看完题目我的思路是输入一个数n,先通过循环判断找到一个数k,使得2的k次方>=n,然后判断等于的情况,如果相等,输出1,如果不等于,计算n与2的k-1次方的差记作sig,则得到输出为1+f(sig),代码如下:
1 #include<iostream> 2 #include<vector> 3 #include<math.h> 4 using namespace std; 5 class Solution 6 public: 7 int NumberOf1(int n) 8 int i = 0; 9 while (pow(2, i) < n) 10 11 i++; 12 13 if (pow(2, i) == n) 14 15 return 1; 16 17 else 18 int sig = n - pow(2, i - 1); 19 int re; 20 re = 1 + NumberOf1(sig); 21 return re; 22 23 24 25 ; 26 int main() 27 28 Solution so; 29 int re = so.NumberOf1(20); 30 cout << re<<endl; 31 return 0; 32
我自己测试结果是对的,结果报错说超时了,emmmmmmm……
然后看了一下答案感觉好简单,这是根据答案修改后的:
1 class Solution 2 public: 3 int NumberOf1(int n) 4 int i = 1,count=0; 5 while (n) 6 7 if (i&n) 8 9 count++; 10 11 n = n >> 1; 12 13 return count; 14 15 16 ;
然鹅,还是超时……
我又改了一下好了,可是问题我也没找到……。这道题其实不用考虑正负的,不用想太多。吐槽一下牛客网的在线编程很辣鸡。我用vc++调试不行的代码居然过了。
1 class Solution 2 public: 3 int NumberOf1(int n) 4 5 int count = 0; 6 int flag = 1; 7 while (flag) 8 9 if (n&flag) 10 11 count++; 12 13 flag = flag << 1; 14 15 return count; 16 17 ;
看了答案的思路真的超级简单,只需要将n和n-1做与运算,即可消除该数字的最右边的1,以此类推,等到最后一个1消除了循环结束,这应该是这道题的最优解:
1 public: 2 int NumberOf1(int n) 3 4 int count = 0; 5 while (n) 6 7 count++; 8 n = n&(n - 1); 9 10 return count; 11
STL有直接可以拿来用的函数,我……记住吧
1 class Solution 2 public: 3 int NumberOf1(int n) 4 5 bitset<32> bit(n); 6 return bit.count(); 7 8
以上是关于剑指offer系列5:二进制中1的个数的主要内容,如果未能解决你的问题,请参考以下文章