剑指Offer(9)-位运算问题

本文深入探讨了位运算的基础知识及实用技巧,包括计算二进制中1的个数、判断整数是否为2的幂,以及计算两个整数转换所需的位变化数。通过具体的代码示例,详细解析了每种方法的实现原理与步骤。

1.0 位运算相关

在这里插入图片描述

1.1 二进制中1出现的次数

第一个做法是将n和1做与运算,若这个数的最低位为1,那么结果为1;若最低位为0,则结果为0,所以在这里可以直接累加来获取末尾1的个数。之后需要将n无符号右移1位消去最低位的1或0,继续重复上述过程,直到n为0;。(为什么不使用有符号右移?当n为负数时,最高位符号位为1,那么在>>之后还会在最高位补1,造成n != 0这个条件永远成立)。这个做法需要循环的次数为n的位数。

public class Solution {
    public int NumberOf1(int n) {
        // >> 带符号右移位,当最高位为符号位且为 1时,右移补位的还是1,为0则补0:1001>>3 = 1111
        // >>> 不带符号的右移位,当最高符号位为1时,右移位补的还是0:1001>>>3 = 0001
        int res = 0;
        while (n != 0) {
            //和1做与运算,若最低位为1则结果为1,若最低位为0则结果为0
            res += n & 1;
            //n无符号右移一位
            n = n >>> 1;
        }
        return res;
    }
}

第二个做法是利用一个整数减去1之后在与原来的整数做与运算,得到的结果相当于二进制中最右边的1变为0,例如1010减去1得1001,1001 & 1010 = 1000,最右边的1变为了0这个性质来统计n中1的个数,这个做法的循环次数为n中含有1的位数。

public class Solution {
    public int NumberOf1(int n) {
        int res = 0;
       	while (n != 0) {
       		res ++;
       		n = (n - 1) & n;
       	}
        return res;
    }
}

1.2 判断一个整数是否为2的幂

如果一个数是2的次方,那么这个数的二进制数中只有一个1;利用 (n - 1) & n会将最右边的1变为0的特性,只需要判断这个数消去1后是否为0则可知道其是否为2的次方(0和负数除外)

class Solution {
    public boolean isPowerOfTwo(int n) {
        if (n <= 0) return false;
        return ((n - 1) & n) == 0;
    }
}

1.3 A改变多少次才能变为B

将整数A、B转化为二进制,请问A需要改变其中的几位才能够转化为B?
例如0110需要改变3位才能变为1000,这里就是异或即可:0110 ^ 1000 = 3

public class Solution {
    // you need to treat n as an unsigned value
    public int solve(int a, int b) {
        return a ^ b;
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BoringRong

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

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

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

打赏作者

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

抵扣说明:

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

余额充值