Binary Search

Keywords: Algorithm

concept

Binary search is a common method to find specific values for ordered arrays. Binary search does not have to traverse the whole sequence, but only needs to pay attention to the boundary and intermediate value of the sequence, so the time complexity can be achieved O ( l o g n ) O(logn) O(logn)

Template

Find keywords in an ordered sequence k e y key The template code of key is as follows

int binarySearch(vector<int>& nums, int key) {
    int l = 0, r = nums.size() - 1, ans = nums.size();
    while (l <= r) {
        int mid = (l + r) / 2;
        if (nums[mid] < key)
            l = mid + 1;
        else
            r = mid - 1, ans = mid;
    }
    return ans;
}

subject

The dichotomous topic template is generally fixed, mainly whether you can think of what to dichotomous and how to dichotomous.

34. Find the first and last position of an element in a sorted array

34. Find the first and last position of an element in a sorted array

This problem requires not only the first position of the element, but also the last position of the element. In the template code, if num [i] < key, we will continue to search the left. If we want to continue to search after we have found the element, we need to modify it to num [i] < = key. The result of this search is greater than k e y key The position of the first element of the key. Therefore, the code of this question is as follows

class Solution {
public:
    int binarySearch(vector<int> &nums, int key, bool next) {
        int l = 0, r = nums.size() - 1, ans = nums.size();
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] < key || (last && nums[mid] <= key))
                l = mid + 1;
            else
                r = mid - 1, ans = mid;
        }
        return ans;
    }
    vector<int> searchRange(vector<int> &nums, int target) {
        int l = binarySearch(nums, target, false),
                r = binarySearch(nums, target, true) - 1;
        if (l <= r)
            return {l, r};
        else return {-1, -1};
    }
};

74. Search two-dimensional matrix

74. Search two-dimensional matrix

According to the question, the element to be searched must be greater than or equal to the first element of the row, so we first perform a binary search on the column to find no greater than t a r g e t target Maximum element of target

Then perform a basic binary search on the row to get the result. The code is as follows

class Solution {
public:
    bool searchMatrix(vector<vector<int>> &matrix, int target) {
        int l = 0, r = matrix.size() - 1, ans = matrix.size(), res = matrix[0].size();
        // Find the position of the first number less than target first
        while (l <= r) {
            int mid = (l + r) / 2;
            if (matrix[mid][0] > target) r = mid - 1;
            else  					     l = mid + 1, ans = mid;
        }
        if (ans < 0 || ans >= matrix.size()) return false;
        l = 0, r = matrix[0].size() - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (matrix[ans][mid] > target) r = mid - 1;
            else						   l = mid + 1, res = mid;
        }
        return matrix[ans][res] == target;
    }
};

33. Search rotation sort array

33. Search rotation sort array

This problem only ensures the local order of the array, but after bisecting the array, it will be found that half of the array is ordered. At this time, you can continue to bisect the ordered array. The code is as follows

class Solution {
public:
    int binarySearch(vector<int> nums, int key, int s, int t) {
        int l = s, r = t - 1, ans = t;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] > key) {
                r = mid - 1;
            } else {
                l = mid + 1;
                ans = mid;
            }
        }
        return (ans < t && nums[ans] == key) ? ans : -1;
    }
    int search(vector<int> &nums, int target) {
        int l = 0, r = nums.size() - 1, ans = -1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] == target) return mid;
            if (nums[l] < nums[mid]) {
                ans = binarySearch(nums, target, l, mid);
                l = mid + 1;
            } else {
                ans = binarySearch(nums, target, mid + 1, r + 1);
                r = mid - 1;
            }
            if (ans >= 0) return ans;
        }
        return ans;
    }
};

153. Find the minimum value in the rotation sort array

153. Find the minimum value in the rotation sort array

This problem is to find the minimum value of the rotated sorting array in the previous problem, that is, the value of the rotation point. We still use the property of partial order to find the minimum value of the array in two. The code is as follows

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

162. Look for peaks

162. Look for peaks

We can use [ l , r ] [l,r] [l,r] to store the interval where there may be peaks, according to m i d mid Mid is scored in two. If num [mid] < num [mid + 1], it indicates that it is in the interval [ m i d + 1 , r ] [mid+1,r] There is a peak in [mid+1,r]. Otherwise, there is a peak in the interval [l,mid]. Therefore, the code is as follows

class Solution {
public:
    int findPeakElement(vector<int>& nums) {
        int l = 0, r = nums.size() - 1;
        while (l <= r) { // Use l,r to indicate the interval where there may be peaks
            int mid = (l + r) / 2;
            if (l == r) return l;
            if (nums[mid] < nums[mid + 1])
                l = mid + 1;//mid+1-r greater
            else
                r = mid;//l-mid larger
        }
        return -1;
    }
};

Posted by atzi on Fri, 15 Oct 2021 14:26:27 -0700