位运算之与

位运算的概念
位运算分为两大类:逻辑位运算符和位运算符
逻辑位运算又分为:位与(&),位或(|),异或(^),按位取反(~)
位运算符分为:左移(<<),右移(>>)

位与(&):二元运算符。两个数进行&运算,可以将其先转化为2进制数,然后从低到高&运算,对于每个位来说,只有两个都为1才为1,否则为0,再转化为十进制数,就是结果。
位或(|):二元运算符。两个数转换为二进制数,然后从低到高进行位或,对于每个位来说,只有两个都为0才为0,否则为1,再将其转换为十进制数就是结果。
异或(^):二元运算符。两个数转换为二进制数,然后从低到高进行位或,对于每个位来说,只有两个数不同的时候为1,否则为0,再将其转换为十进制数就是结果。
按位取反(~):一元运算符。当前数字转换成二进制后,所有的数1变0,0变1。
左移(<<):二元运算符。比如 x < < y x << y x<<y表示 x x x左移 y y y位。就是将 x x x转换成二进制后,然后对它的所有位向左偏移 y y y位。末尾补0,所以如果左移一位可以看成将 x x x乘2。
右移(>>):二元运算符。比如 x > > y x >> y x>>y表示 x x x右移 y y y位。就是将 x x x转换成二进制后,然后对它的所有位向右偏移 y y y位。如果 x x x是非负数则高位补0,如果是负数则高位补1。所以如果右移一位可以看成将 x x x除2,并且向下取整

异或的性质:相同的数异或为0,0与任何数异或为他本身,并且满足交换律和结合律。

4的幂一定时候2的幂,2的幂不一定是4的幂。当2的偶数次幂 2 2 x 2^{2x} 22x%3=1,2的奇数次幂 2 2 x + 1 2^{2x+1} 22x+1%3=2,所以只要在2次幂的基础上加上模3为1即可。

191. 位1的个数

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int num = 0;
        while(n != 0){
            n &= n - 1;
            num++;
        }
        return num;
    }
}
//使用 n & 1 得到二进制末尾是否为 1;
//n & (n−1),其运算结果恰为把 nn 的二进制位中的最低位的 11 变为 00 之后的结果。
public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int num = 0;
        for(int i = 0; i < 32; ++i){
            if((n & (1 << i) ) != 0){
                num++;
            }
        }
        return num;
    }
}
//左移运算符(<<)用来将一个数的各二进制位全部左移若干位,移动的位数由右操作数指定,右操作数必须是非负值,其右边空出的位用0填补,高位左移溢出则舍弃该高位

201. 数字范围按位与

class Solution {
    public int rangeBitwiseAnd(int left, int right) {
        while(left < right){
            right &= right - 1;
        }
        return right;
    }
}
//通过清除最低位的1,来获取计算两个二进制字符串的公共前缀

461. 汉明距离
^运算:只有两个1之间异或才是1。

class Solution {
    public int hammingDistance(int x, int y) {
        int z = x ^ y;
        int s = 0;
        while(z != 0){
            z &= z - 1;
            s++;
        }
        return s;
    }
}
//求两个位运算合起来的1的数量
// ^ 参加运算的两个数据,按二进制位进行“异或”运算。
//两数异或运算,每次看最低位是不是1,
class Solution {
    public int hammingDistance(int x, int y) {
        int s = x ^ y, res= 0;
        while (s != 0) {
            res+= s & 1;
            s >>= 1;
        }
        return res;
    }
}

剑指 Offer 56 - II. 数组中数字出现的次数 II

class Solution {
    public int singleNumber(int[] nums) {
        Map<Integer,Integer> map = new HashMap<>();
        //将其存入哈希表中:若该元素不存在则存入表中,并计数为1,若已经存在获取次数并加1.
        for(int i = 0; i < nums.length; ++i){
            int x = map.getOrDefault(nums[i], 0);
            map.put(nums[i], x + 1);
        }
        //遍历出出现次数为1的情况
        //这时候使用keySet()方法获取所有的key值
        for (int i : map.keySet()) {
            if(map.get(i) == 1){
                return i;
            }
        }
        return 0;
    }
}

/*Map.getOrDefault(Object key, V defaultValue)方法的作用是:
  当Map集合中有这个key时,就使用这个key值;
  如果没有就使用默认值defaultValue。
*/
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秦 羽

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

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

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

打赏作者

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

抵扣说明:

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

余额充值