【技巧总结】java位运算

【技巧总结】java位运算位运算的技巧总结,配合十道力扣题目,帮你快速入门。

位运算可以大幅度提高代码的运行效率,是每个人都应熟练掌握的解题技巧,首先感谢英雄大佬的b站视频,感兴趣的话可以前往b站一睹为快:可能会占据你陪女朋友的时间,但是你要相信……

位运算两大类:

逻辑位运算符
位移运算符

逻辑位运算符包括:
逻辑与(&&):只有两个运算数都为true是才是true,其他则为false。
逻辑或(||):如果其中一个或两个运算数都是true,那么返回true,如果两个运算数都是false,那么返回false。

位移运算符包括:
位与运算符(&):只有对应的两个二进位均为1时,结果位才为1 ,否则为0。
位或运算符(|):只要对应的两个二进位有一个为1时,结果位就为1。
异或运算符(^):只有对应的两个二进制位相同的时候,结果位返回0,否则返回1。
按位取反运算符(~):转换为二进制数后,0变1,1变0。
左移运算符(<<):把位按指定的值向左移动对应的位数,超过的位将丢失,空位补0,左移也可以看作是对此数乘以2。
右移运算符(>>):把位按指定的值向右移动对应的位数,移动过程中,正数最高位补0,负数最高位补1,右移也可以看作是对此数除以2。

举一些栗子:
1.231. 2 的幂
在这里插入图片描述
在这里插入图片描述

分析:当这个是小于或者等于0的时候,一定不是2的幂,我们可以知道二进制最高位为 1,其余所有位均为 0。所以这个数如果是2的幂,一定是1加上若干个0,那么我们减去一,也就是0加上若干个1,我们让这两个数进行位与运算,那么一定是若干个0。也就是我们有:n & (n – 1) == 0,所以此题可解。

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

2.342. 4的幂
在这里插入图片描述

分析:4的幂一定是2的幂,但是2的幂不一定是4的幂。我们可以推出,2的偶数次幂模3等于1,2的奇数次幂模3等于2。而2的偶数次幂正好是4的幂,所以我们可以知道,如果一个数字是2的幂,并且它模3等于1,那么它一定就是4的幂。

class Solution { 
   
    public boolean isPowerOfFour(int n) { 
   
        return (n > 0) && (n & (n - 1))== 0 && (n % 3 == 1);
    }
}

3.191. 位1的个数
在这里插入图片描述

分析:我们把一个数a的二进制数假设为(…1000),那么我们剪去1,就可以得到了(…0111),我们让(…1000)&(…0111),那么就可以得到(…0000),于是我们这样就可以把a的二进制数最低位的1消去了。我们通过这种操作,就可以把所有的1都消去了,然后统计消去的1的个数,我们就可以得到结果了。

public class Solution { 
   
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) { 
   
        int number = 0;//记录1的个数
        while(n!=0){ 
   
            n &= (n - 1);
            ++number;
        }
        return number;
    }
}

4.面试题 16.01. 交换数字
在这里插入图片描述

分析:我们先看一个运算规则,规则:0^0=0; 0^1=1; 1^0=1; 1^1=0;所以我们可以得到两个相同的数进行异或运算,可以得到0,那么一个数和0进行异或运算,就是得到这个数的本身。我们看下面这张图,这样就可以将a与b进行交换了在这里插入图片描述

class Solution { 
   
    public int[] swapNumbers(int[] numbers) { 
   
        numbers[0] = numbers[0]^numbers[1];
        numbers[1] = numbers[0]^numbers[1];
        numbers[0] = numbers[0]^numbers[1];
        return numbers;
    }
}

5.136. 只出现一次的数字
在这里插入图片描述

分析:我们先看一个运算规则,规则:0^0=0; 0^1=1; 1^0=1; 1^1=0;所以我们可以得到两个相同的数进行异或运算,可以得到0,那么一个数和0进行异或运算,就是得到这个数的本身。那么我们只要不断异或下去,就可以得到把出现两次的数全部解决,所以就可以剩下只出现了一次的数字。

class Solution { 
   
    public int singleNumber(int[] nums) { 
   
        int number = 0;
        for(int i = 0; i < nums.length; i++){ 
   
            number = number^nums[i];
        }
        return number;
    }
}

6.461. 汉明距离
在这里插入图片描述

分析:由下图可知,异或完去求所得结果上1的个数就是所求的汉明距离。
在这里插入图片描述

class Solution { 
   
    public int hammingDistance(int x, int y) { 
   
        int n = x^y;
        int number = 0;
        while(n != 0){ 
   
            n &= (n - 1);
            number++;
        }
        return number;
    }
}

7.693. 交替位二进制数
在这里插入图片描述

分析:我们对这个正整数的二进制进行两位两位判断,从尾部开始,向头部两位两位判断,如果相邻的这两个数是11或者是00,那么就不符合题意。我们又可以知道,二进制的00对应十进制就是0,二进制的11对应十进制就是3,于是我们可以让3的二进制不断与这个数的二进制数进行&运算,我们看一张图:在这里插入图片描述

class Solution { 
   
    public boolean hasAlternatingBits(int n) { 
   
        while(n!=0){ 
   
            if( (n & 3)==3 || (n & 3) == 0 ){ 
   
                return false;
            }
            n>>=1;
        }
        return true;
    }
}

8.1863. 找出所有子集的异或总和再求和
在这里插入图片描述
在这里插入图片描述

分析:我们给定一个数组,将里面的子集进行分解:在这里插入图片描述
如果二进制对应的位置上有1,就证明在集合里面,否则就不在。
在这里插入图片描述
上面的意思是,在i这个数的二进制表示中,从低到高第 j 位是否是1,把 1 的数字对应的位都进行异或,得到的结果累加到最终结果就是答案。

class Solution { 
   
    public int subsetXORSum(int[] nums) { 
   
        int answer,sum = 0;
        for(int i = 0; i < (1<<nums.length); i++){ 
   
            answer = 0;
            for(int j = 0; j < nums.length; j++){ 
   
                if((i&(1<<j))!=0){ 
   
                    answer^=nums[j];
                }
            }
            sum = sum + answer;
        }
        return sum;
    }
}

9.371. 两整数之和
在这里插入图片描述

分析:首先我们可以看一下十进制的情况: 9+3=12,
第一步:相加各位的值,但是不算进位,得到2。
第二步:计算进位值,得到10。
第三步:重复上述两步,得到相加值为12。
¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
我们可以同理计算二进制值相加: 比如101和111
第一步:相加各位的值,但是不算进位,得到010,二进制的每位相加就相当于各位做异或操作,101^111。
第二步:计算进位值,得到1010,相当于各位进行与操作得到101,再向左移一位得到1010,(101&111)<<1。
第三步:重复上述两步,各位相加 010^1010=1000,进位值为100=(010 & 1010)<<1。
继续重复上述两步:1000^100 = 1100,进位值为0,此时我们跳出循环,1100为最终结果。当我们的进位为0,即为最终所求结果。

class Solution { 
   
    public int getSum(int a, int b) { 
   
        return b == 0 ? a : getSum(a^b,(a&b) << 1);
    }
}

10.面试题 05.01. 插入
在这里插入图片描述

分析:先把N的第i到第j都归零,然后把M插入到N的对应位置,归零可以使用位与&运算,将其和第k位为0,其余位为1的二进制数进行运算,达到消零操作:在这里插入图片描述
然后我们在将N左移i位,和现在的数进行位或,就可以得到结果:
在这里插入图片描述

class Solution { 
   
    public int insertBits(int N, int M, int i, int j) { 
   
        for(int k = i; k <= j; k++){ 
   
            N &= ~((long)1<<k);
        }
        return N|(M<<i);
    }
}

学习位运算最好的时间是在大一,其次就是现在。
在这里插入图片描述

今天的文章【技巧总结】java位运算分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/8984.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注