求一个正整数的二进制表示包含多少1 - 每天五分钟搞定Java面试

Java中,int类型占四字节,即32位,这里我们假设正整数n是int型,那么正整数32的二进制表示为:

0000 0000 0000 0000 0000 0000 0010 0000

法一:位移法

我们对每一位进行判断,首先判断最低位,如果是1,那1的总个数加1,然后右移一位后,再判断最低位,位移32次,进行循环判断。
这种操作思路很简单,但存在一定的问题:不管n的二进制表示中含有多少个1,都需要位移32次,每次判断最低位是否为1,比较耗时。

法二:求与法

这种方法借助n&(n-1)这个操作,它可以消除n的二进制表示中的最后一个1,消除多少次,就有多少个1

法三:查表法

这种方法的思路是以空间换时间,即我先把每一个正整数对应的二进制1的个数用数组存储下来,如下:
res[1] = 1;
res[2] = 1;
res[3] = 2;
res[4] = 1;



res[32767] = 14;


如果要计算n的二进制表示中1的个数,直接返回res[n]即可。时间复杂度为O(1)
但这种方法有个问题:改表示结果的数组占用较大的内存空间,在内存空间有限制的情况,这种方法不可行。
接下来我们思考一下怎么减少内存空间的使用。算法的设计,本身是一个时间复杂度和空间复杂度的折衷,增加计算次数,往往能够减少存储空间。
思路:把正整数n分解为低16位正整数n1,高16位正整数n2
n1查一次表,其二进制表示包含x个1
n2查一次表,其二进制表示包含y个1
则n的二进制表示包含x+y个1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值