Problem

Given two integers left and right that represent the range [left, right], return the bitwise AND of all numbers in this range, inclusive.

Examples

Example 1:

Input: left = 5, right = 7
Output: 4

Example 2:

Input: left = 0, right = 0
Output: 0

Example 3:

Input: left = 1, right = 2147483647
Output: 0

Solution

Method 1 - Bitwise and Operator

Bitwise-AND of any two numbers will always produce a number less than or equal to the smaller number.

Consider the following example, for desired range [5, 12]:

12 ---- 1100
11 ---- 1011
10 ---- 1010
9  ---- 1001
8  ---- 1000
7  ---- 0111
6  ---- 0110
5  ---- 0101

Starting from 12, the loop will first do 12 & 11 = 8

Next iteration, the loop will do 8 & 7 = 0

why did we skip anding of 10,9? Because even if we did so, the result would eventually be and'ed with 8 whose value would be lesser than equal to 8.

Hence, you start from the range end and keep working your way down the range till you reach the start.

Code

Java
public int rangeBitwiseAnd(int left, int right) {
	while(right > left) {
		right = right & (right-1);
	}
	return left&right;
}

We don’t have to return left&right:

public int rangeBitwiseAnd(int left, int right) {
	int ans = right;
	while(right > left) {
		ans = right & (right-1);
		right = ans;
	}
	return ans;
}
Further Optimization

this can be optimised further, if there exists 2^n in the range.. result would be zero. If you see example above, 8&7 = 0.

public int rangeBitwiseAnd(int left, int right) {
    //~ find next 2^n bigger than left and if that is within the range result would be zero
    int psq = Integer.highestOneBit(left); 
    int next = psq << 1;
    if(next > left && next <= right) {
	    return 0; 
	}
    
    while(left < right)  right = right&(right-1);
    
    return right;
}