剑指offer 第十五题 位运算 二进制中1的个数

  • 把一个整数减去1之后再和原来的整数做位与运算,得到的结果相当于把整数的二进制表示中最右边的1变为0

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

思路分析

  • 第一种思路:
    二进制表示和1与运算,结果为1,说明最右边位置为1;右移判断各个位置是否为1
    • 缺点:如果是负数的情况下,符号位是1,左边补得一直为1,这样最终数字会变成0xFFFFFFFF,从而陷入死循环
  • 第二种思路:二进制表示不变,让1不断左移,相与,来判断二进制表示的各个位置是否为1
    • 缺点:如果数字为32位,那么要循环32次1的左移,和1的与操作。
  • 第三种思路:n的二进制表示-1=把n的二进制表示最右边的一个1变为0,最右边为1的位记为m,那么m右边的全部变为1(右边的结构被破坏,所以我们要从右向左计数),m左边的数字保持不变。 循环终止条件:两个数相与变为0.

代码

public int NumberOf1(int n) {
       int count=0;
       while(n!=0){
			count++;
			n=n&(n-1);//最右边的1先计算进去,然后得到他前边的结构继续进行运算
		}
		return count;
    }

题目2:一条语句判断一个数是不是2的整数次幂

  • 二进制表示中如果只有1位为1,那么就是2的整数次幂;
  • 让一个数和他的n-1相与,如果结果为0,就说明只有一位为1.
  • return n&(n-1)==0

题目3:输入两个数m和n,判断m的二进制表示要经过几次改变才能变为n

  • 第一步:m和n求异或得到一个结果(结果中有几个1,说明有几位不同)(异或等于1说明不相同)
  • 第二步:统计异或结果中有几个1
public static int getNumberOf1(int n,int m) {
		n=n^m;
		return NumberOf1(n);
	}
	
	public static int NumberOf1(int n) {
		int count=0;
		while(n!=0) {
			count++;
			n=n&(n-1);
		}
		return count;
	}

你可能感兴趣的:(剑指Offer,二进制,剑指offer,1的个数)