常见技巧
https://blog.csdn.net/Apple_hzc/article/details/83830118
https://blog.csdn.net/weixin_39003229/article/details/90488161
https://www.wandouip.com/t5i204483/
//https://blog.csdn.net/zmazon/article/details/8262185
public class 位运算 {
public static void main(String[] args) {
System.out.println(getMaxInt());
System.out.println(getMinInt());
System.out.println(getMaxLong());
System.out.println(multi2Power(3,3));//3*2^3=24
System.out.println(isOddNumber(9));
swap(4,3);
System.out.println(absNum(-11101));
System.out.println(maxNum(9,-1));
System.out.println(isSameSign(8,1));
System.out.println(isFactorialofTwo(45));
}
//不用临时变量 交换两个数
public static void swap(int a,int b){
System.out.println("交换前a: "+a+",b: "+b);
a^=b;//a=a^b;
b^=a;//b=(a^b)^b=a
a^=b;//a=(a^b)^a=b
System.out.println("交换后a: "+a+",b: "+b);
}
//判断两个数符号是否一致
//对于任何数x,都有x^x=0,x^0=x
//判断符号位 0和1异或时符号位为1 其他均为0
public static boolean isSameSign(int x, int y){ //有0的情况例外 8和0判定为一样了
System.out.println(x ^ y);
return (x ^ y) >= 0; // true 表示 x和y有相同的符号, false表示x,y有相反的符号。
}
//计算2的n次方
public static int getFactorialofTwo(int n){//n > 0
return 2 << (n-1);//2的n次方
}
//判断一个数是否是2的次方
/*如果是2的幂,n一定是100... n-1就是011....
所以做与运算结果为0*/
public static boolean isFactorialofTwo(int n){
return n>0?(n&(n-1))==0:false;
}
//对2的n次方取余
public static int mod2(int m,int n){//n为2的次方
return m & (n - 1);
/*如果是2的幂,n一定是100... n-1就是1111....
所以做与运算结果保留m在n范围的非0的位*/
}
//取平均值
public static int getAverage(int x, int y) {
return (x + y) >> 1;
}
//从低位到高位,取n的第m位
public static int getBit(int n, int m){
return (n>>(m-1))&1;
}
//从低位到高位.将n的第m位置1
public static int setBitToOne(int n, int m){
return n | (1 << (m-1));
/*将1左移m-1位找到第m位,得到000...1...000
n在和这个数做或运算*/
}
//从低位到高位,将n的第m位置0
public static int setBitToZero(int n, int m){
return n & ~(1 << (m-1));
/* 将1左移m-1位找到第m位,取反后变成111...0...1111
n再和这个数做与运算*/
}
//判断一个数奇数true 偶数false
public static boolean isOddNumber(int n){
return (n&1)==1;//偶数末位0 奇数末位1
}
//获得int类型最大值
public static int getMaxInt(){
//return (1<<31)-1;//写法1
//return ~(1<<31);//写法2
return (1<<-1)-1;//写法3
}
//获得int类型最小值
public static int getMinInt(){
//return 1<<31;//写法1
return 1<<-1;//写法3
}
//获得long类型最大值
public static long getMaxLong(){
// return ((long)1<<127)-1;//写法1
// return ~((long)1<<127);//写法2
return ((long)1<<-1)-1;//写法3
}
//n乘以2的m次方
public static int multi2Power(int n,int m){
return n<<m;//除以 n>>m
}
//取绝对值
/* n>>31 取得n的符号,若n为正数,n>>31等于0,若n为负数,n>>31等于-1
若n为正数 n^0=0,数不变,若n为负数有n^-1 需要计算n和-1的补码,然后进行异或运算,
结果n变号并且为n的绝对值减1,再减去-1就是绝对值 */
public static int absNum(int n){
return (n ^ (n >> 31)) - (n >> 31);
}
//取两数较大值
public static int maxNum(int a,int b){
return b & ((a-b) >> 31) | a & (~(a-b) >> 31);
/*如果a>=b,(a-b)>>31为0,否则为-1*/
}
//取两数较小值
public static int min(int a,int b){
return a & ((a-b) >> 31) | b & (~(a-b) >> 31);
/*如果a>=b,(a-b)>>31为0,否则为-1*/
}
}
136. 只出现一次的数字
class Solution {
public int singleNumber(int[] nums) {
//一个数与所有其他数异或 结果都不为0
//结果就是这个数字
//此题确定了其他数字都是两次 彼此注定抵消
//全部异或 结果就是单个的那个数
int res=0;
for(int i=0;i<nums.length;i++){
res^=nums[i];
}
return res;
}
}
//另一种HashMap法
class Solution {
public int singleNumber(int[] nums) {
if(nums==null||nums.length==0){
return 0;
}
Map<Integer,Integer> map=new HashMap<>();
for(int n:nums){
map.put(n,map.getOrDefault(n,0)+1);
}
for(int key:map.keySet()){
if(map.get(key)==1){
return key;
}
}
return 0;
}
}
268. 丢失的数字
class Solution {
public int missingNumber(int[] nums) {
if(nums==null||nums.length==0){
return -1;
}
int len=nums.length;
int sum=0;
for(int n:nums){
sum+=n;
}
// int expected=0;
// for(int i=1;i<len+1;i++){
// expected+=i;
// }
int expected=len*(len+1)/2;
return expected-sum;
}
}
class Solution {
public int missingNumber(int[] nums) {
if(nums==null||nums.length==0){
return -1;
}
int missing=nums.length;
for(int i=0;i<nums.length;i++){
missing^=i^nums[i];
}
return missing;
}
}
191. 位1的个数
踩坑注意
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count=0;
while(n!=0){
//count+=((n&1)==1)?1:0;
count+=n&1;
n>>>=1;//逻辑右移 高位填补0
//n>>=1;//会超时 算术右移 一直补充符号位1
}
return count;
}
}
改进
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count=0;
while(n!=0){
count++;
n&=n-1;
}
return count;
}
}
231. 2 的幂
class Solution {
public boolean isPowerOfTwo(int n) {
return n>0?(n&(n-1))==0:false;
}
}
https://leetcode-cn.com/problems/power-of-two/solution/2de-mi-by-leetcode-solution-rny3/
n&(n-1)
n&(-n)
class Solution {
public boolean isPowerOfTwo(int n) {
return n > 0 && (n & -n) == n;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/power-of-two/solution/2de-mi-by-leetcode-solution-rny3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
326. 3的幂
class Solution {
public boolean isPowerOfThree(int n) {
if(n<=0) return false;
if(n==1) return true;
if(n%3!=0) return false;
else return isPowerOfThree(n/3);
}
}
class Solution {
public boolean isPowerOfThree(int n) {
//换底公式 log3(n)为整数 log10(n)/log10(3)
return (Math.log10(n)/Math.log10(3))%1==0;
}
}
342. 4的幂
class Solution {
public boolean isPowerOfFour(int n) {
return n>0 && (n&(n-1))==0 && n % 3==1;
}
}
461. 汉明距离
类似于191
class Solution {
public int hammingDistance(int x, int y) {
//异或 0^0=0 0^1=1 1^1=0
return Integer.bitCount(x^y);//内置函数 计算1的位数
}
}
class Solution {
public int hammingDistance(int x, int y) {
int res=x^y;
int count=0;
while(res!=0){
res&=res-1;
count++;
}
return count;
}
}
201. 数字范围按位与
右边只要有一个0 与的结果就是0
只要计算最长公共前缀就行
题解
class Solution {
public int rangeBitwiseAnd(int left, int right) {
while(left<right){
right&=right-1;
}
return right;
}
}
371. 两整数之和
https://leetcode-cn.com/problems/sum-of-two-integers/solution/li-yong-wei-cao-zuo-shi-xian-liang-shu-qiu-he-by-p/
class Solution {
public int getSum(int a, int b) {
while(b!=0){
//先计算无进位 的 和
int tmpSum=a^b;
// 计算 进位 &和左移1位 更新b用于下一次和a相加
b=(a&b)<<1;
//更新a
a=tmpSum;
}
return a;
}
}
public int getSum(int a, int b) {
return b == 0 ? a : getSum((a ^ b), (a & b) << 1);
}
190. 颠倒二进制位
public class Solution {
// you need treat n as an unsigned value
public int reverseBits(int n) {
int cnt=32;
int res=0;
while(cnt-->0){
res<<=1;
res+=n&1;
n>>=1;
// cnt--;
}
return res;
}
}
898. 子数组按位或操作
在这里插入代码片