整型数其二进制表示中”1“的个数

初看这个题目,给人的第一感觉是要把整数转化成二进制表示,然后在求出里面的1的个数,于是诞生了第一种解法

1、除余法

我们都知道”除余法“可以将十进制数转化为其二进制数,对于余数,从下往上取构成其二进制表示。那么我们可以根据每次的余数是否为1,判断1的个数

int Count(int n)
{
	int cnt=0;
	while(n)
	{
		if(n%2==1)  //如果余数为1,则个数加1
			cnt++;
		n=n/2;
	}
	
	return cnt;
}

时间复杂度:O(logn)
空间复杂度:O(1)  //即用了一个变量cnt

2、移位+与操作

对于一个整数,我们可以进行移位操作,每向右移一位,相当于原来整数除以2。
那么我们可以先从最后一位进行判断,统计是否为1;然后向右移一位,然后再判断最后一位,如此循环下去
通过对整数移位:
int Count(int n)
{
	int cnt=0;
	while(n)
	{
		cnt+=n&1;
		n=n>>1;
	}
	
	return cnt;
}

时间复杂度:O(m)  //m表示整数的二进制位数
空间复杂度:O(1)

3、与操作

可以通过求n和n-1的与操作来实现,因为n-1相当于对n中最右的1及其后面进行了非操作,如10的二进制1010,9的二进制1001,最后的两位由”10“变成了”01“,
因而n中当前‘1’及其后面的都变成了0

初始: n=1010 (二进制)
10&=(10-1) 得到1010 & 1001= 1000, cnt=1
8&=(8-1) 得到1000 & 0111= 0000, cnt=2
停止循环

int Count(int n)
{
	int cnt=0;
	while(n)
	{
		n&=(n-1);
		cnt++;
	}
	
	return cnt;
}

时间复杂度:O(M) //M表示整数二进制表示中1的位数
空间复杂度:O(1)

扩展问题:给定两个正整数(二进制表示)A和B,问把A变成B需要改变多少位?

解析:也即两者二进制位有多少位不同,可用第二种方法:移位

int DiffCount(int m, int n)
{
	int cnt=0;
	int flag=1;
	while(m && n)
	{
		if((m&flag)!=(n&flag)) //每次比较最后一位是否相同 
			cnt++;
		m >>=1; //右移一位 
		n >>=1;
	}
	
	while(m)
	{
		if(m&flag ==1) //由于此时n为0,故只需统计m中剩余的1的个数 
			cnt++;
		m >>=1;
	}
	
	while(n)
	{
		if(n&flag==1) //由于此时m为0,故只需统计n中剩余的1的个数 
			cnt++;
		n >>=1;
	}
	
	return cnt;
}















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值