文章目录
位运算 n & (n-1)、Leetcode231、面试题 05.06
作用
n & (n-1)作用:将最低位的1改为0。
举例
6 110 //原始数
& 5 101
--------
4 100 //6 最低位 1 改为 0
& 3 011
--------
0 000 //4 最低位 1 改为 0
应用
判断一个正整数是否为2的幂
如果(n & (n-1)) == 0则这个正整数为2的幂。
解释
2的幂的二进制特点:有且只有一个1。
如果一个正整数二进制最低位1改为0后,没有其他的1了,那么这个数是2的幂。
求一个数二进制中1的个数
while(n != 0) {
count++;
n &= (n-1);
}
计算N!的质因数2的个数
N!的质因数2的个数公式:[N / 2] + [N / 4] + [N / 8] + ...
解释
[N / 2]在不大于N的数中,是2的倍数的有[N / 2]个,各贡献一个2。
[N / 4]在不大于N的数中,是4的倍数的有[N / 4]个,各贡献一个2,虽然4的倍数可以贡献2个2,但是在[N / 2]中已经贡献了一个,所以这里只贡献一个。
…以此类推
举例求解
N=21(10101)
[N / 2] + [N / 4] + [N / 8] + ...可以分解为[(16 + 4 + 1) / 2] + [(16 + 4 + 1) / 4] + ...
可以得出只需求[10000/2]+...``[00100/2]+...``[00001/2]+...即可
求[10000/2]+...
[10000 / 2] 01000
[10000 / 4] 00100
[10000 / 8] 00010
[10000 / 16] 00001
[10000 / 2] + [10000 / 4] + [10000 / 8] + [10000 / 16] = 01111 = 10000 - 1
同理可得其他位
[00100/2]+... = 00011 = 00100 - 1
[00001/2] = 00000 = 00001 - 1
可得
(10101)!的质因数2的个数为10000 - 1 + 00100 - 1 + 00001 - 1 = 10101 - 3(二进制表示中1的个数)
由此推出
N!的质因数2的个数为N - (N二进制中1的个数)
Leetcode 231 2的幂
求一个数是否为2的幂。很简单,不再赘述。
public boolean isPowerOfTwo(int n) {
if (n <= 0) return false;
return (n&(n-1)) == 0;
}
面试题 05.06. 整数转换
求从A数转成B数,需要改变二进制多少位。
思路
求A和B异或后二进制中1的个数。
代码
public int convertInteger(int A, int B) {
int diff = A ^ B;
int ans = 0;
while (diff != 0) {
ans++;
diff &= (diff-1);
}
return ans;
}

本文介绍了位运算n&(n-1)在计算中的应用,如判断一个正整数是否为2的幂、求二进制中1的个数以及计算N!的质因数2的个数。此外,还讲解了LeetCode231题目的解法和面试题05.06整数转换的策略,通过计算异或后的二进制1的个数来确定转换所需的位数变化。
1万+

被折叠的 条评论
为什么被折叠?



