剑指offer(牛客)---11.二进制中1的个数

题目描述

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

 

public  int NumberOf1(int n) {
    	if(n==0) {
    		return 0;
    	}
    	int count=0;
    	while(n!=0) {
    		count++;
    		n=n&(n-1);
    	}
		return count;

    }

此解法是我在牛客网评论中看到的,确实是我所理解中最优的解法,下面我来分析一下此最优解法:

首先当二进制是0的时候直接返回0,这个毋庸置疑;

很多人第一眼看见会问代码里面没有考虑到负数的二进制情况(别急听我分析)

我们首先考虑正式,我们首先的情况所有的数不管是什么语言,其底层都是二进制编码,因为计算机只能读懂二进制.所以我们做题的时候根本不用考虑要不要将十进制转换成二进制的问题.

假设 n=22,那么它的二进制就是0001 0110 然后

进入循环-->

                 count=1,

                 n与(n-1)进行逻辑&运算-->0001 0110  & 0001 0101 -->0001 0100

                 (其实其本质就是从后面数1,数完一个1就把1拿掉,继续然后)

又进入循环-->           

                 count=2,

                 n与(n-1)进行逻辑&运算-->0001 0100  & 0001 0011 -->0001 0000

又进入循环-->           

                 count=3,

                 n与(n-1)进行逻辑&运算-->0001 0000  & 0000 1111 -->0000 0000

最后退出循环;

 

现在考虑负数,负数的话一共两步:

       1.将负数先变成反码,

       2.数它反码中1的个数,

第一步,操作系统已经帮我们做了,你觉得你还要干什么吗?

第二步,直接又是在二进制中数1的个数,不是一样的吗?难得正数的二进制和反码的二进制还有不同?

所以这题就这么简单的完美解决!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值