Skip to main content

Binary Search

Binary search may be one of the most intuitive algorithms: when the search space is sorted, then we can make a guess first (usually the middle in the range of [left, right)) to see whether the "guessed" value fits the condition or not. Based on the result with the "guessed" value,  we can adjust the search range by removing either the first half or the second half.

Some key points:

1. The search space may be an abstract one. The basic understanding is that: if the "middle" value is Okay, and all the values smaller (or larger) than it are also Okay, then we can consider to use binary search;

2. In some special cases, binary search is NOT always the most efficient method for sorted data (for example, two sum problem with a sorted array);

3. The boundary conditions are tricky to handle.


The template of the lower_bound index (the index of the first element equal to the target if exists; or the index of the first element (maybe the end of the array) larger than the target if not)

class Solution {
public:
    int lower_bound(vector<int>& nums, int target) {
        int left = 0, right = nums.size();
        while(left < right) {
            int mid = left + (right - left) / 2;
            if(nums[mid] < target) left = mid + 1;
            else right = mid;
        }
        return left;
    }
};


The template of the upper_bound index: (the index of the first element (maybe the end of the array) larger than the target)

class Solution {
public:
    int upper_bound(vector<int>& nums, int target) {
        int left = 0, right = nums.size();
        while(left < right) {
            int mid = left + (right - left) / 2;
            if(nums[mid] <= target) left = mid + 1;
            else right = mid;
        }
        return left;
    }
};


Notes:

1. the only difference is: one is < and the other is <=;

2. if the target does not exist in the array, they are the same.




Example


Easy Level

Medium Level

Hard Level

Interview Questions


Upper Layer

Comments

Popular posts from this blog

Dynamic Programming - Easy Level - Question 1

Dynamic Programming - Easy Level - Question 1 Leetcode 1646  Get Maximum in Generated Array You are given an integer n. An array nums of length n + 1 is generated in the following way: nums[0] = 0 nums[1] = 1 nums[2 * i] = nums[i] when 2 <= 2 * i <= n nums[2 * i + 1] = nums[i] + nums[i + 1] when 2 <= 2 * i + 1 <= n Return the maximum integer in the array nums​​​. Constraints: 0 <= n <= 100 Analysis: This question is quick straightforward: the state and transitional formula are given; the initialization is also given. So we can just ready the code to iterate all the states and find the maximum. See the code below: class Solution { public: int getMaximumGenerated(int n) { int res = 0; if(n<2) return n; vector<int> f(n+1, 0); f[1] = 1; for(int i=2; i<=n; ++i) { if(i&1) f[i] = f[i/2] + f[i/2+1]; else f[i] = f[i/2]; // cout<<i<<" "<<f[i]<<endl; ...

Bit Manipulation - Medium Level

 Leetcode 416 Partition Equal Subset Sum Given a non-empty array nums containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. Constraints: 1 <= nums.length <= 200 1 <= nums[i] <= 100 Analysis: There are different ways to solve this problem, such as dp with a time complexity of O(N^2). Since N is small to this question, so it is Okay to pass OJ. Besides the small N, the value of each element is also very small. So this gives us some chance to use "space to trad off time". The data structure to be used is bitset. For bitset, each bit can be either 0 or 1. The index of that bit can be used as the corresponding sum. When the bit is 1, means there is a sum with the value of its index. When a new number comes, this number needs to be added to all the previous sums, to form new "previous" sums. Thus for each number, we need to go through all the previous sums, the time co...