Featured image of post Bitwise Operation

Bitwise Operation

Bitwise ooperation is a technique that operates directly on the binary bit level.It is characterized by extremely high speed because the CPU natively supports these operations.It is commonly used in performance optimization,low-level programming,algorithm design and other fields.

Common Techniques(Java Code Examples)

Determine parity

1
2
boolean idOdd=(n&1)==1;
boolean idEven=(n&1)==0;

Mutiply and divide by powers of 2(watch out for overflow)

1
2
int doubleVal=n<<1;
int halfVal=n>>1;

Swap two numbers(without using a temperary varible)

1
2
3
4
int a=5,b=3;
a^=b;
b^=a;
a^=b;

Get the absolute value(avoid possible negative overflow with Math.abs)

1
2
3
4
5
6
// 1.
int abs=(n^(n>>31))-(n>>31);

// 2.
int mask=n>>31;
int abs=(n+mask)^mask;

Check if a number is a power of 2

1
boolean isPowerOfTwo=(n>0)&&((n&(n-1))==0);

Clear the least significant 1 bit

1
n&=(n-1);

Get the least significant 1 bit(lowbit)

1
int lowbit=n&-n;

Count the number of 1s in binary(Brian Kernighan’s algorithm)

1
2
3
4
5
int count=0;
while(n!=0){
    n&=(n-1);
    count++;
}

Check if the signs are the same

1
boolean sameSign=((a^b)>=0);

Module a power of 2(equivalent to n%m,where m is a power of 2)

1
int mod=n&(m-1);

Notes in Java

Shift length modulo operation

1
2
3
int x=1;
x<<32;
x>>33;

The effect of unsigned right shift »> on negative numbers

1
2
int negative=-1;
System.out.println(negative>>>1);

Operator precedence

1
if((a&b)==0) { ... }

Type promotion

During the bitwise operations,byte,short,and char are automotically promoted to int,and the result is also int.Therefore,after shifting a byte left and assigning it back,a cast is required.

Bitmask and State Management in Java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public static final int READ=1<<0;
public static final int WRITE=1<<1;
public static final int EXEC=1<<2;

int permissions= READ | WRITE ;

if((permissions & READ)!=0) { ... }

permissions|=EXEC;
permissions&=~READ;

LeetCode

136.Number that appears only once

The XOR operation satisfies: a^a=0,a^0=a.

1
2
3
4
5
6
7
8
9
class solution{
    public int singleNumber(int[] nums){
        int res=nums[0];
        for(int i=1;i<nums.length;i++){
            res^nums[i];
        }
        return res;
    }
}

137.Number that appears only once II

Method 1:Bit-by-bit counting(32-bit)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class solution{
    public int singleNumber(int[] nums){
        int res=0;
        for(int i=0;i<32;i++){
            int cnt=0;
            for(int num:nums){
                cnt+=(num>>i)&1;
            }
            cnt%=3;
            res|=(cnt<<i);
        }
        return res;
    }
}

Mathod 2: Finite State Machine

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class solution{
    public int singleNumber(int[] nums){
        int ones=0,twos=0;
        for(int num:nums){
            ones=(ones^num)&~twos;
            twos=(twos^num)&~ones;
        }
        return ones;
    }
}

Method 3: Common

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class solution{
    public int singleNumber(int[] nums){
        Map<Integer,Integer> map=new HashMap<>();
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        for(Map.Entry<Integer,Integer> entry:map.entrySet()){
            if(entry.getValue()==1){
                return entry.getKey();
            }
        }
        return -1;
    }
}

260.Number that appears only once III

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class solution{
    public int[] singleNumber(int[] nums){
        int xor=0;
        for(int num:nums){
            xor^=num;
        }

        int mask=xor&-xor;

        int a=0,b=0;
        for(int num:nums){
            if((num&mask)==0){
                a^=num;
            }else{
                b^=num;
            }
        }
        return new int[]{a,b};
    }
}

268.Missing Number

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class solution{
    public int missingNumber(int[] nums){
        int xor=0;
        int n=nums.length;
        for(int i=0;i<=n;i++){
            xor^=i;
        }
        for(int num:nums){
            xor^=num;
        }
        return xor;
    }
}

The Set Mismatch

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class solution{
    public int[] findErrorNums(int[] nums){
        int n=nums.length;
        int xor=0;

        for(int i=0;i<=n;i++){
            xor^=i;
        }
        for(int num:nums){
            xor^=num;
        }

        int mask=xor^-xor;

        int a=0,b=0;
        for(int i=0;i<=n;i++){
            if((num&mask)!=0){
                a^=i;
            }else{
                b^=i;
            }
        }
        for(int num:nums){
            if((num&mask)!=0){
                a^=num;
            }else{
                b^=num;
            }
        }
        for(int num:nums){
            if(num==0){
                return new int[]{a,b};
            }
        }
        return new int[]{b,a};
    }
}

421.Maximum XOR of Two Numbers in an Array

Method 1: Trie(Prefix Tree)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class solution{
    class TrieNode{
        TrieNode[] children=new TrieNode[2];
    }
    public int findMaximumXOR(int[] nums){
        TrieNode root=new TrieNode();

        for(int num:nums){
            for(int i=31;i>=0;i--){
                int bit=(num>>i)&i;
                if(node.children[bit]==null){
                    node.children[bit]=new TrieNode();
                }
                node=node.children[bit];
            }
        }
        int max=0;
        for(int num:nums){
            TrieNode node=root;
            int cur=0;
            for(int i=31;i>=0;i--){
                int bit=(num>>i)&i;
                int target=1-bit;
                if(node.children[target]!=nulll){
                    cur|=(1<<i);
                    node=node.children[target];
                }else{
                    node=node.children[bit];
                }
            }
            max=Math.max(max,cur);
        }
        return max;     
    }
}

Method 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class solution{
    public int findMaximumXOR(int[] nums){
        int max=0,mask=0;
        for(int i=31;i>=0;i--){
            mask|=(1<<i);
            Set<Integer> set=new HashSet<>();
            for(int num:nums){
                set.add(num&mask);
            }
            int candidate=max|(1<<i);
            for(int prefix:set){
                if(set.contains(prefix^candidate)){
                    max=candidate;
                    break;
                }
            }
        }
        return max;
    }
}

231.Power of 2

1
2
3
4
5
class solution{
    public boolean isPowerOfTwo(int n){
        return (n>0)&&(n&(n-1)==0);
    }
}

191.Number of 1 Bits

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class solution{
    public int hamminWeight(int n){
        int count=0;
        while(n!=0){
            n&=n-1;
            count++;
        }
        return count;
    }
}

338.Counting Bits

Method 1:

1
2
3
4
5
6
7
8
9
class solution{
    public int[] countBits(int n){
        int[] ans=new int[n+1];
        for(int i=0;i<=n;i++){
            ans[i]=Integer.bitCount(i);
        }
        return ans;
    }
}

Mathod 2:

1
2
3
4
5
6
7
8
9
class solution{
    public int[] countBits(int n){
        int[]  dp=new int[n+1];
        for(int i=1;i<=n;i++){
            dp[i]=dp[i>>i]+(i&1);
        }
        return dp;
    }
}

Method 3:

1
2
3
4
5
6
7
8
9
class solution{
    public int[] countBits(int n){
        int[] dp=new int[n+1];
        for(int i=1;i<=n;i++){
            dp[i]=dp[i&(i-1)+1];
        }
        return dp;
    }
}

201.Bitwise AND of Numbers Range

Method 1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class solution{
    public int rangeBitwiseAnd(int left,int right){
        int shift=0;
        while(left<right){
            left>>=1;
            right>>=1;
            shift++;
        }
        return left<<shift;
    }
}

Method 2:

1
2
3
4
5
6
7
8
class solution{
    public int rangeBitwiseAnd(int left,int right){
        while(left<right){
            right&=(right-1);
        }
        return right;
    }
}

461.Hamming Distance

Method 1:

1
2
3
4
5
class solution{
    public int hammingDistance(int x,int y){
        return Integer.bitCount(x^y);
    }
}

Method 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class solution{
    public int hammingDistance(int x,int y){
        int xor=x^y;
        int count=0;
        while(xor!=0){
            count+=xor&1;
            xor>>=1;
        }
        return count;
    }
}

Method 3: Brian Kernighan

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class solution{
    public int hammingDistance(int x,int y){
        int xor=x^y;
        int count=0;
        while(xor!=0){
            xor&=(xor-1);
            count++;
        }
        return count;
    }
}

78.Subset

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class solution{
    public List<List<Integer>> subsets(int[] nums){
        List<List<Integer>> res=new ArrayList<>();
        int n=nums.length;
        int total=1<<n;
        for(int mask=0;mask<total;mask++){
            List<Integer> subset=new ArrayList<>();
            for(int i=0;i<n;i++){
                if((mask&(1<<i))!=0){
                    subset.add(nums[i]);
                }
            }
            res.add(subset);
        }
        return res;
    }
}

1879.Sum of Minimum XOR Values of Two Arrays

Method 1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class solution{
    public int minimumXORSum(int[] num1,int[]  num2){
        int n=num1.length;
        int size=1<<n;
        int[] dp=new int[size];
        Arrays.fill(dp,Integer.MAX_VALUE);
        dp[0]=0;
        for(int mask=0;mask<size;mask++){
            if(dp[mask]==Integer.MAX_VALUE) continue;
            int cnt=Integer.bitCount(mask);
            if(cnt==n) continue;

            for(int j=0;j<n;j++){
                if((mask&(1<<j))==0){
                    int newMask=mask|(1<<j);
                    int val=dp[mask]+(num1[cnt]^num2[j]);
                    if(val<dp[newMask]){
                        dp[newMask]=val;
                    }
                }
            }
        }
        return dp[size-1];
    }
}

Method 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class solution{
    public int minimumXORSum(int[] num1,int[] num2){
        int n=num1.length;
        int size=1<<n;
        int INF=0x3f3f3f3f;
        int[][] dp=new int[n][size];
        for(int i=0;i<n;i++){
            Arrays.fill(dp[i],INF);
        }
        for(int j=0;j<n;j++){
            dp[0][1<<j]=num1[0]^num2[j];
        }
        for(int i=1;i<n;i++){
            for(int mask=0;mask<size;mask++){
                if(Integer.bitCount(mask)!=i+1) continue;
                for(int j=0;j<n;j++){
                    int prevMask=mask^(1<<j);
                    if(dp[i-1][prevMask]!=INF){
                        dp[i][mask]=Math.min(dp[i][mask],
                            dp[i-1][prevMask]+(num1[i]^num2[j]));
                    }
                }
            }
        }
        return dp[n-1][size-1];
    }
}

371.Sum of Two Integers

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class solution{
    public int getSum(int a,int b){
        while(b!=0){
            int carry=(a&b)<<1;
            int a=a^b;
            b=carry;
        }
        return a;
    }
}

1486.Array XOR Operation

Method 1:

1
2
3
4
5
6
7
8
9
class solution{
    public int xorOperation(int n,int start){
        int ans=0;
        for(int i=0;i<n;i++){
            ans^=(start+2*i);
        }
        return ans;
    }
}

Method 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class solution{
    public int xoroperation(int n,int start){
        int s=start>>1,e=n&start&1;
        int ret=sumXor(s-1)^sumXor(s+n-1);
        return ret<<1 | e;
    }
    public int sumXor(int x){
        if(x%4==0){
            return x;
        }
        if(x%4==1){
            return 1;
        }
        if(x%4==2){
            return x+1;
        }
        return 0;
    }
}
Licensed under Genshin Impact NB