leetcode位运算小技巧


一、原题目链接

1.面试题 05.07. 配对交换
2.476. 数字的补数
3.191. 位1的个数
4.面试题 16.01. 交换数字

二、使用方法

面试题 05.07. 配对交换

交换数字的奇数偶数位
(位0与位1交换,位2与位3交换,以此类推)
例如:
输入2(10) 输出1(01)
输入14(1110) 输出13(1101)

方法:
0xaaaaaaaa=10101010101010101010101010101010
0x55555555=01010101010101010101010101010101

1.保留奇数位与偶数位分别储存
原数字分别与0xaaaaaaaa,0x55555555进行与&运算

2.偶数位向右移动一位,奇数位向左移动一位
(如果写在同一行需要注意的是移位>>/<<的运算先于与&运算,因此需要加括号)

3.奇数位偶数位合并
将得到的两个结果进行或|运算就是结果

代码:

var exchangeBits = function(num) {
    let even=(num&0xaaaaaaaa)>>1;
    let odd=(num&0x55555555)<<1;
    return even|odd;
};

476. 数字的补数

输入正整数,输出它的补数。补数是对该数的二进制表示取反
例如:
输入13(1101) 输出2(0010)
输入9(1001 )输出6(0110)

方法:
这里我运用的是javascript,因为javascript的二进制特定是32位,因此使用否~运算最左位会变成符号位1,结果就会变为负数

这里运用的是异或^1运算
0^1=1
1^1=0
可以得知与1进行异或运算会使原位变成相反数字

将原数字转成2进制再遍历每一位分别进行异或^1运算,将结果加入字符串

代码:

var findComplement = function(num) {
    let res='';
    num=num.toString(2);
    for(let i=0;i<num.length;i++){
        res+=num[i]^1;
    }
    return parseInt(res,2)
};

191. 位1的个数

输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数
例如:
输入1101 输出3
输入1001 输出2

方法:根据布赖恩·克尼根算法

1.设置循环条件
直到n=0

2.算法规律
将n和n-1进行与&运算
例:
11011010 (n)
11011001 (n-1)
进行与&运算后
11011000
相当于去掉了尾数的1,因此只需要记录循环次数即可

代码:

var hammingWeight = function(n) {
    let res=0;
    while(n!=0){
        n=n&(n-1);
        res++;
    }
    return res;
};

面试题 16.01. 交换数字

编写一个函数,不用临时变量,直接交换numbers = [a, b]中a与b的值。
输入: numbers = [5,3]
输出: [3,5]

方法:利用异或运算
例如:
5=0101
3=0011
0101^0011=0110 存在number[0]
0110^0011=0101 存在number[1]
0110^0101=0011 存在number[0]

var swapNumbers = function(numbers) {
    numbers[1]^=numbers[0];
    numbers[0]^=numbers[1];
    numbers[1]^=numbers[0];
    return numbers;
};

总结

使用一些位运算的方法可以减少花费的时间

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值