标签:应该 names 根据 计算 个数 调试 code int using
先说下原码,反码和补码的概念。在计算机中用第一位表示数的正负,正数为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 }
标签:应该 names 根据 计算 个数 调试 code int using
原文地址:https://www.cnblogs.com/neverland0718/p/10972782.html