力扣190. 颠倒二进制位+191. 位1的个数

第一百零九天 --- 力扣190. 颠倒二进制位+191. 位1的个数

题目一

力扣:190. 颠倒二进制位

在这里插入图片描述
在这里插入图片描述

思路

常规

1、所谓颠倒,就是把原来的最右面的位数放在最左面
2、所以我们对原串,每次都 &1 取出最右面的位,再 | 进入答案即可
3、每次答案<<,原数>>即可。

细节

一定要注意,答案,应该先移位,流出地方,再进行 | 运算。

进阶(分治法)

1、我们想,所谓的整体颠倒,我们把32长度的串,从中间劈开,把右面的部分放在左半部分前面,不就得了。
2、但是这两部分内部必须得是颠倒过了的,然后借助递归的思路,逐渐二分。
3、所以,先颠倒长度为2的串,每两个颠倒了,再颠倒长度*2,再次执行,直到颠倒长度=32。
4、再加之这是位运算,各个位之间互不打扰,互不影响,所以各个长度的颠倒,在各个位之间可以并行,所以只需要执行5次即可得到答案

颠倒示例:
在这里插入图片描述

代码

常规

class Solution {
public:
	uint32_t reverseBits(uint32_t n) {
		uint32_t ans = 0;
		for (int i = 0; i < 32; i++) {
			ans <<= 1;//这里相当于往一个数字上进行拼数,先移位,留出位置,再|
			ans |= (n & 1);
			n >>= 1;

		}
		return ans;
	}
};

所有代码均以通过力扣测试
(经过多次测试最短时间为):
在这里插入图片描述
在这里插入图片描述

进阶

class Solution {
private:
	const uint32_t M1 = 0x55555555; // 01010101010101010101010101010101
	const uint32_t M2 = 0x33333333; // 00110011001100110011001100110011
	const uint32_t M4 = 0x0f0f0f0f; // 00001111000011110000111100001111
	const uint32_t M8 = 0x00ff00ff; // 00000000111111110000000011111111
public:
	uint32_t reverseBits(uint32_t n) {
		n = ((n&M1) << 1) | (n >> 1 & M1);//注意优先级,<< 高于 &
		n = ((n&M2) << 2) | (n >> 2 & M2);
		n = ((n&M4) << 4) | (n >> 4 & M4);
		n = ((n&M8) << 8) | (n >> 8 & M8);
		return n >> 16 | n << 16;
	}
};

所有代码均以通过力扣测试
(经过多次测试最短时间为):
在这里插入图片描述

在这里插入图片描述

题目二

力扣:191. 位1的个数

在这里插入图片描述
在这里插入图片描述

思路

常规

直接32位逐位统计1的个数即可

进阶

我们只要1的个数,所以0无意义,所以我们通过 n&(n-1)的方法,每算一次就干掉一个1,就可以跳过无用的0。

代码

常规

class Solution {
public:
	int hammingWeight(uint32_t n) {
		int ans = 0;
		for (int i = 0; i < 32; i++) {
			ans += n & 1;
			n >>= 1;
		}
		return ans;
	}
};


所有代码均以通过力扣测试
(经过多次测试最短时间为):
在这里插入图片描述
在这里插入图片描述

进阶

class Solution {
public:
	int hammingWeight(uint32_t n) {
		int ans = 0;
		while (n > 0) {//我只想知道1出现的次数,所以和0没关系,所以把无意义的0越过去
			n = n & (n - 1);//每次算完都会干掉1个1,起到了越过0的作用
			ans++;
		}
		return ans;
	}
};

所有代码均以通过力扣测试
(经过多次测试最短时间为):
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JLU_LYM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值