zoukankan      html  css  js  c++  java
  • Binary Search

    When to use binary search:

    * 我们知道解空间在一个区间 [i,j]

    * valid解是解空间的一个点(也可以看作是只有一个点的range)或者一个range的起始点或者结束点

    * range之外的点都不是valid解

    想法一般都两种:

    * 直接找到解 (比如classical binary search)

    * 找中间一个点,验证这个点,通过验证结果能知道valid解在左边或者右边区间

    Template:

        int binarySearchTemplate() {
            int i = [lower_bound_of_solution], j = [upper_bound_of_solution];               // valid range is [i,j]
            // while (i + 1 < j) {    // Overflow if i is INT_MAX
            while (i < j - 1) {
                int m = i + (j - i) / 2;
                if (m is valid solution)
                    return m;
                else if (solution is on left side)         // valid range will be [i,m-1] or [i,m]
                    j = m - 1, or m;
                else                                        // valid range will be [m,j] or [m+1,j]
                    i = m + 1, or m;
            }
            // now check if i or j is valid solution
        }

    457. Classical Binary Search https://www.lintcode.com/en/problem/classical-binary-search/

    class Solution {
    public:
        /*
         * @param nums: An integer array sorted in ascending order
         * @param target: An integer
         * @return: An integer
         */
        int findPosition(vector<int> &nums, int target) {
            if (nums.size() == 0)
                return -1;
                
            int i = 0, j = nums.size()-1;   // [i,j] is the all valid range
            while (i+1 < j) {               // Loop will break if there're 1 or 2 items left
                int m = i + (j - i) / 2;
                if (nums[m] == target)
                    return m;
                else if (target > nums[m])
                    i = m + 1;
                else
                    j = m - 1;
            }
            if (nums[i] == target)          // We need to check if i or j (i and j might be same) is valid
                return i;
            else if (nums[j] == target)
                return j;
            else
                return -1;
        }
    };

    35. Search Insert Position https://leetcode.com/problems/search-insert-position/description/

    class Solution {
    public:
        int searchInsert(vector<int>& nums, int target) {
            int i = 0, j = nums.size();     // valid range is [0,nums.size()]
            while (i+1 < j) {
                int m = i + (j - i) / 2;
                if (nums[m] == target)
                    return m;
                else if (target > nums[m])
                    i = m + 1;              // if target > nums[m], valid range will be [m+1,j]
                else
                    j = m;                  // if target < nums[m], vlaid range will be [i,m]
            }
            if (target <= nums[i])          // only if target <= nums[i], result will be i; otherwise j.
                return i;
            return j;
        }
    };
     

    69. Sqrt(x) https://leetcode.com/problems/sqrtx/description/

    class Solution {
    public:
        int mySqrt(int x) {
            int i = 0, j = x;               // valid range is [0,x]
            while (i + 1 < j) {
                long m = i + (j - i) / 2;
                if (m * m == x)
                    return m;
                else if (m * m > x)         // if target < m*m, valid range will be [i,m-1]
                    j = m - 1;
                else                        // if target > m*m, valid range will be [m,j]
                    i = m;
            }
            if (j * j <= x)                 // j is valid only when j*j <= x
                return j;
            return i;
        }
    };

    34. Search for a Range https://leetcode.com/problems/search-for-a-range/description/

    class Solution {
    public:
        vector<int> searchRange(vector<int>& nums, int target) {
            if (nums.size() == 0)   return vector<int>( { -1, -1} );
            
            int low = -1;
            int i = 0, j = nums.size()-1;
            while (i + 1 < j) {
                int m = i + (j - i) / 2;
                if (nums[m] == target)
                    j = m;
                else if (nums[m] > target)
                    j = m - 1;
                else
                    i = m + 1;
            }
            if (nums[i] == target)
                low = i;
            else if (nums[j] == target)
                low = j;
            
            if (low == -1)  return vector<int>( { -1, -1} );
            
            i = low, j = nums.size()-1;
            while (i + 1 < j) {
                int m = i + (j - i) / 2;
                if (nums[m] == target)
                    i = m;
                else if (nums[m] > target)
                    j = m - 1;
                // else
                //    i = m + 1;      // should never happen
            }
            if (nums[j] == target)
                return vector<int>( { low, j} );
            else
                return vector<int>( { low, i} );
        }
    };

    33. Search in Rotated Sorted Array https://leetcode.com/problems/search-in-rotated-sorted-array/description/

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

    81. Search in Rotated Sorted Array II https://leetcode.com/problems/search-in-rotated-sorted-array-ii/description/

    class Solution {
    public:
        bool search(vector<int>& nums, int target) {
            if (nums.size() == 0)   return false;
            
            int i = 0, j = nums.size()-1;
            while (i + 1 < j) {
                int m = i + (j - i) / 2;
                if (nums[m] == target)
                    return true;
                else if (nums[i] < nums[m]) 
                {
                    if (nums[i] <= target && target < nums[m])
                        j = m - 1;
                    else
                        i = m + 1;
                }
                else if (nums[i] > nums[m]) {
                    if (nums[m] < target && target <= nums[j])
                        i = m + 1;
                    else
                        j = m - 1;
                }
                else {  // nums[i] == nums[m]
                    i++;
                }
            }
            
            return (nums[i] == target || nums[j] == target);
        }
    };

    153. Find Minimum in Rotated Sorted Array https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/description/

    class Solution {
    public:
        int findMin(vector<int>& nums) {     
            if (nums.size() == 0)   return -1;
            
            int i = 0, j = nums.size()-1;
            while (i + 1 < j) {
                int m = i + (j - i) / 2;
                if (nums[i] < nums[j])  // not rotated
                    return nums[i];
                else if (nums[i] < nums[m]) 
                    i = m + 1;
                else
                    j = m;
            }
            
            return min(nums[i], nums[j]);
        }
    };

    154. Find Minimum in Rotated Sorted Array II https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/description/

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

    278. First Bad Version https://leetcode.com/problems/first-bad-version/description/

    // Forward declaration of isBadVersion API.
    bool isBadVersion(int version);
    
    class Solution {
    public:
        int firstBadVersion(int n) {
            int i = 1, j = n;
            while (i < j - 1) {
                int m = i + (j - i) / 2;
                if (isBadVersion(m))
                    j = m;
                else
                    i = m+1;
            }
            
            return isBadVersion(i) ? i : j;
        }
    };

    378. Kth Smallest Element in a Sorted Matrix https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/description/

    class Solution {
    public:
        int m, n;
        int kthSmallest(vector<vector<int>>& matrix, int k) {
            m = matrix.size();
            n = matrix[0].size();
            int i = matrix[0][0], j = matrix[m-1][n-1];
            while (i < j - 1) {
                int m = i + (j - i) / 2;
                int mc = getSmallerEqualCount(matrix, m);
                if (mc >= k)
                    j = m;
                else
                    i = m + 1;
            }
            return getSmallerEqualCount(matrix, i) >= k ? i : j;
        }
        int getSmallerEqualCount(vector<vector<int>>& matrix, int v) {
            int res = 0;
            for (int i = 0; i < m; i++) {
                auto it = upper_bound(matrix[i].begin(), matrix[i].end(), v);
                res += it - matrix[i].begin();
            }
            return res;
        }
    };
  • 相关阅读:
    JAVA并发-CountDownLatch
    【转载】Makedown数学公式语法
    算法的时间复杂度
    JVM-卡表(Card Table)
    sync.WaitGroup的使用以及坑
    go 多协程爬取图片
    go ioutial 读取写入文件
    go 下载图片
    go 正则 爬取邮箱代码
    go 解析path
  • 原文地址:https://www.cnblogs.com/JTechRoad/p/8975580.html
Copyright © 2011-2022 走看看