LeetCode题目:二进制中1的个数

题目描述:

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

第一种做法:

先判断整数最右边的一位是不是1,通过将输入的数n与1做按位与运算,如果结果不等于0,说明最右边的一位是1,则count加一,然后将n右移一位;如此循环,直至n为0结束循环,返回count。
要注意的是,对于有符号数的右移,在左边补进来的数是符号为,如果是正数,补的是0,如果是负数,补的是1。所以这种做法对于负数来说会出现死循环的情况。

第二种做法:

既然移动输入的数n有可能造成死循环,那就移动用于判断数,也就是先用1和n做按位与运算,判断最右边的数是不是1,然后将判断的数左移1位,与n再次按位与运算,判断右边第二个数是不是1。如此循环,直至判断的数比n还大,说明判断完了,返回count。
这种做法要求,输入的数有多少位就要判断多少次。

第三种做法:

这种做法是,输入的数里面有多少个1,就做多少次判断:
可以发现,如果把一个整数减去1,在和原整数做按位与运算,会把整数最右边的1变成0,例如1100,减1后得到1011,按位与之后得到1000,就把最右边的1变成了0。从这个特点出发,每次将n减1与n做按位与运算,直至n变为0,返回count。

代码(Java):

public class Solution {
	public static void main(String[] args) {
		int n = 11;
		System.out.println(hammingWeight2(n));
	}
	
	/**
	 * 用n-1按位与n的做法
	 * @param n
	 * @return
	 */
	public static int hammingWeight(int n) {
		int count = 0;
		//只要n不等于0,就首先count+1,然后再建议与原来的n按位与运算
		while(n!=0) {
			count++;
			n = (n-1) & n;
		}
		return count;
	}
	
	/**
	 * 每次判断最右边的数是不是1的做法
	 * 容易引起死循环
	 * @param n
	 * @return
	 */
	public static int hammingWeight1(int n) {
		int count = 0;
		while(n!=0) {
			if((n & 1) != 0) {
				count++;
			}
			n = n >> 1;
		}
		return count;
	}
	
	/**
	 * 用于判断的标志位每次左移一位,直到标志位代表的数比输入的数大,每次比较一位
	 * @param n
	 * @return
	 */
	public static int hammingWeight2(int n) {
		int count = 0;
		int flag = 1;
		while(flag <= n) {
			if((n & flag) != 0) {
				count++;
			}
			flag = flag << 1;
		}
		return count;
	}

}

你可能感兴趣的:(剑指offer,习题,java,算法,leetcode)