剑指offer 二进制中1的个数
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
代码一:
1 class Solution { 2 public: 3 int NumberOf1(int n) { 4 int count = 0; 5 while (n) { 6 if (n & 1) { 7 count++; 8 } 9 n >>= 1; 10 //n = n & (n - 1); 11 12 } 13 return count; 14 } 15 };
有问题,出现死循环,原因在于如果输入的是负数, 如0x80000000, 右移一位之后会变成0xC0000000, 而不是0x40000000,经过多次移位,最终会变成0xFFFFFFFF
代码二:我们不右移数字,而是左移1.这种做法,32位的整数需要左移32次
1 class Solution { 2 public: 3 int NumberOf1(int n) { 4 int count = 0; 5 unsigned int flag = 1; 6 while (flag) { 7 if (n & flag) { 8 count++; 9 } 10 flag <<= 1; 11 //n = n & (n - 1); 12 13 } 14 return count; 15 } 16 };
代码三:每一次 n & (n - 1)操作相当于把n对应二进制最右边的1变成0,循环次数为n中1的个数。
class Solution { public: int NumberOf1(int n) { int count = 0; while (n) { count++; n &= n - 1; } return count; } };
相关题目:
1、输入两个整数m和n, 计算需要改变m的二进制表示中的多少位才能得到n。
思路:第一步:将两个数进行异或操作(^),得到两个数的二进制差别,
第二步:统计异或结果中1的个数。
2、用一条语句判断一个整数是否是2的整数次方。
思路:如果一个数是2的整数次方,那么它的二进制表示中有且只有一位是1, 那么n & (n - 1) = 0。
越努力,越幸运