Algorithm_Binary Search - xwu36/LeetCode GitHub Wiki

Binary Search

We basically ignore half of the elements just after one comparison. Compare x with the middle element. If x matches with middle element, we return the mid index. Else If x is greater than the mid element, then x can only lie in right half subarray after the mid element. So we recur for right half. Else (x is smaller) recur for the left half.

1. Regular Binary Search:

return the index of the target number in a sorted array, if there is no such a number, return -1;

input: data = [1, 2, 3],

key = 0, 1, 2, 3, 4

output: res = -1, 0, 1, 2, -1

public int binarySearch(int[] data, int key) {
	int low = 0;
	int high = data.length - 1;      
	while(high >= low) {
		int middle = (low + high) / 2;
		if(data[middle] == key) {
			return middle;
		}
		if(data[middle] < key) {
			low = middle + 1;
		}
		if(data[middle] > key) {
			high = middle - 1;
		}
	}
	return -1;
}

2. Find the position

Given an array containing distinct elements, use the given number to substitute a number in a sorted array, find the right position for this given number which makes the array after replacement still sorted.

input: data = [3, 4, 6],

key = 0, 2, 3, 5, 8

output: res = 0, 0, 0, 1, 2

explain: for key = 0, if it is inserted into the input array, it should be at the first position.

public int binarySearchForReplacement(int[] data, int key) {
	int low = 0;
	int high = data.length - 1;      
	while(high >= low) {
		int middle = (low + high) / 2;
		if(data[middle] == key) {
			return middle;
		}
		if(data[middle] < key) {
			low = middle + 1;
		}
		if(data[middle] > key) {
			high = middle - 1;
		}
	}
	return low - 1 < 0 ? 0 : low - 1;                 // the only difference compared with the above code
}

int this case, the largest number less or equal than key would be replaced. change return low - 1 to low, can have the least number greater than key been replaced

See Problem #74. Search a 2D Matrix

3. Find The Upper Bound and Lower Bound using Binary Search

The lower and upper bound of a binary search are the lowest and highest position where the value could be inserted without breaking the ordering.

Take, for example, a sorted range
1 2 3 4 5 5 5 6 7 9
In a binary search for 3, we will have
   v-- lower bound
1 2 3 4 5 5 5 6 7 9
     ^-- upper bound
And in a binary search for 5:
       v-- lower bound
1 2 3 4 5 5 5 6 7 9
             ^-- upper bound
public int binarySearchForUpperbound(int[] data, int key) {
	int low = 0;
	int high = data.length;      
	while(high > low) {
		int middle = (low + high) / 2;
		if(data[middle] <= key) {
			low = middle + 1;
		}else{
			high = middle;
		}
	}
	return low;               // the only difference compared with the above code
}
public int binarySearchForLowerBound(int[] data, int key) {
	int low = 0;
	int high = data.length;      
	while(high > low) {
		int middle = (low + high) / 2;
		if(data[middle] >= key) {
			high = middle;
		}else{
			low = middle + 1;
		}
	}
	return low;               // the only difference compared with the above code
}

4. Find Minimum in Rotated Sorted Array

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

public int findMin(int[] nums) {
        int low = 0;
        int high = nums.length - 1;
        while(low < high){
            int middle = (low + high) / 2;
            if(nums[middle] < nums[nums.length - 1]){
                high = middle;
            }else{
                low = middle + 1;
            }
        }
        return nums[low];
}

If the array may contain duplicates.

public int findMin(int[] num) {
        int lo = 0;
        int hi = num.length - 1;  
        while(lo < hi) {
            int mid = lo + (hi - lo) / 2;        
            if (num[mid] > num[hi]) {
                lo = mid + 1;
            }
            else if (num[mid] < num[hi]) {
                hi = mid;
            }
            else { // when num[mid] and num[hi] are same
                hi--;
            }
        }
        return num[lo];
}

See Problem #153. Find Minimum in Rotated Sorted Array

See Problem #154. Find Minimum in Rotated Sorted Array II