一些有用的位运算操作符

463 阅读1分钟

位运算操作符运算速度要比算术操作符要快,所以记录下刷算法题学习到的位运算操作符。

注:适用于正整数

1. num >> 1 ( n / 2 )

可用于算法中得到中间数

001000 // 8
000100 // 右移一位得到4
// 相当于 8/2 = 4
// Math.floor(4) = 4;

001101 // 13
000110 // 右移一位得到6
// 相当于 13/2 = 6.5 
// Math.floor(6.5) = 6;

2. 交换a和b的值

a = a ^ b;
b = a ^ b; // b = a ^ b ^ b 等同于 b = a;
a = a ^ b; // a = a ^ b ^ a 等同于 a = b;

3. 获取n化为二进制后最右的1 : num & (~num + 1 )

适用于找一组无序整数数组中,仅有一个数出现了奇数次,其余数出现了偶数次的题(Leetcode No.260)

var singleNumber = function (nums) {
    let eor = 0;
    for (var i in nums) {
        eor ^= nums[i]; // eor = a ^ b;
    }
    let right = eor & (~eor + 1); // 得到只有最右第n为为1的数
    let other = 0;
    for (var i in nums) {
        // 位运算符中除了>>,<<,>>>这三个优先级高于==,=== 号,其他优先级低于==、===。
        if ((right & nums[i]) === 0) { // 将nums中的数分为两部分,一部分是第n为是1的,另一部分不是1的,假设a第n位是1,那么b一定在另一半,===0 意思是与b一堆与,最后得到b
            other ^= nums[i]; // 这时候other肯定是b;
        }
    }
    return [other, other ^ eor];
};

4. 获取第i位的值:(num >>  i ) & 1

001101 // 13
// 获取13右数第三位的值(从0开始)
 000001 // 13 >> 3
&000001
=000001 // 1 

5. 合并各个位的1:res |= ( 1 <<  i )