【负雪明烛】「循环」与「分治」解法
2021年3月29日 09:59
各位题友大家好! 今天是 @负雪明烛 坚持日更的第 64 天。今天力扣上的每日一题是「190. 颠倒二进制位」。
解题思路
今天的题目是要求将一个数字,把其二进制翻转,求得到的另外一个二进制数。
方法一:循环
这是最容易想到的方法了,每次把 res 左移,把 $n$ 的二进制末尾数字,拼接到结果 res 的末尾。然后把 $n$ 右移。
举一个 8 位的二进制进行说明:
| i | n | res |
|---|---|---|
| - | 11001001 | - |
| 0 | 1100100 | 1 |
| 1 | 110010 | 10 |
| 2 | 11001 | 100 |
| 3 | 1100 | 1001 |
| 4 | 110 | 10010 |
| 5 | 11 | 100100 |
| 6 | 1 | 1001001 |
| 8 | - | 10010011 |
代码如下:
###Python
class Solution:
# @param n, an integer
# @return an integer
def reverseBits(self, n):
res = 0
for i in range(32):
res = (res << 1) | (n & 1)
n >>= 1
return res
###C++
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t res = 0;
for (int i = 0; i < 32; ++i) {
res = (res << 1) | (n & 1);
n >>= 1;
}
return res;
}
};
- 时间复杂度:$O(1)$
- 空间复杂度:$O(1)$
方法二:分而治之
有另外一种不使用循环的做法,类似于归并排序。
其思想是分而治之,把数字分为两半,然后交换这两半的顺序;然后把前后两个半段都再分成两半,交换内部顺序……直至最后交换顺序的时候,交换的数字只有 1 位。
以一个 8 位的二进制数字为例:
![]()
代码如下:
###Python
class Solution:
# @param n, an integer
# @return an integer
def reverseBits(self, n):
n = (n >> 16) | (n << 16);
n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8);
n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4);
n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2);
n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1);
return n;
###C++
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
n = (n >> 16) | (n << 16);
n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8);
n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4);
n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2);
n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1);
return n;
}
};
- 时间复杂度:$O(1)$
- 空间复杂度:$O(1)$
刷题心得
位运算还是很有意思的。
参考资料:
OK,以上就是 @负雪明烛 写的今天题解的全部内容了,如果你觉得有帮助的话,求赞、求关注、求收藏。如果有疑问的话,请在下面评论,我会及时解答。
关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。
祝大家牛年大吉!AC 多多,Offer 多多!我们明天再见!