二分查找合集

最简单的二分查找

找target的左边界,如果没有则返回-1

重点在于nums[mid] == target的时候,收缩右边界

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


        if(left == nums.size() || nums[left] != target)
            return -1;
        else
            return left;
    }

找target的右边界,如果没有则返回-1

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


        // 结束的时候right == left - 1, right就是left左边的那个
        // 因为每次收紧区间前,left = mid + 1,所以在循环结束后left不可能是target,只有right才有可能是target
        // 画一画就知道了,left/mid/right先会在同一个位置,然后left右移right不变
        if(right < 0 || nums[right] != target)
            return -1;
        else 
            return right;
    }

利用找左边界的方法,实现lower_bound的功能(找到第一个大于等于target的位置)

重点在于nums[mid] == target的时候,收缩右边界

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

        
        // 这里非常简洁,因为left会根据数据的情况保持为0或者变为nums.size()
        return left;
    }
posted @ 2020-08-19 20:48  joeyzzz  阅读(234)  评论(0编辑  收藏  举报