参考C++库函数来划分二分查找元素的四个边界

704. 二分查找

参考:二分查找有几种写法?它们的区别是什么?

# 求非降序范围[first, last)内第一个不小于value的值的位置 
def lower_bound(array, first, last, value): 
    while first < last: # 搜索区间[first, last)不为空 
        mid = first + (last - first) // 2 # 防溢出
        if array[mid] < value: first = mid + 1 
        else: last = mid 
    return first # last也行,因为[first, last)为空的时候它们重合

def upper_bound(array, first, last, value): 
    while first < last:
        mid = first + (last - first) // 2
        if array[mid] <= value: first = mid + 1 
        else: last = mid 
    return first
  • lower_bound(value)本身找的是x>=value的下界,若为last则不存在(第二个箭头)

  • upper_bound(value)本身找的是x>value的下界,若为last则不存在(第四个箭头)

  • lower_bound(value)-1即为x< value的上界,若为first-1则不存在(第一个箭头)

  • upper_bound(value)-1即为x<= value的上界,若为first-1则不存在(第三个箭头)

class Solution {
    public int search(int[] nums, int target) {
        int first = 0, last = nums.length;
        while (first < last) {
            int mid = first + ((last - first) >> 1);
            if (nums[mid] < target) first = mid + 1;
            else last = mid;
        }
        if (first == nums.length || nums[first] != target) return -1;
        return first;
    }
}

34. 在排序数组中查找元素的第一个和最后一个位置

这题对应上文图片中第二个箭头和第三个箭头。

class Solution {
    int target;

    public int[] searchRange(int[] nums, int target) {
        this.target = target;
        int lower = lower_bound(nums, 0, nums.length);
        int upper = upper_bound(nums, 0, nums.length);
        return new int[]{lower, upper};
    }

    public int lower_bound(int[] nums, int first, int last) {
        while (first < last) {
            int mid = first + ((last - first) >> 1);
            if (nums[mid] < target) first = mid + 1;
            else last = mid;
        }
        if (first == nums.length || nums[first] != target) return -1;
        return first;
    }

    public int upper_bound(int[] nums, int first, int last) {
        while (first < last) {
            int mid = first + ((last - first) >> 1);
            if (nums[mid] <= target) first = mid + 1;
            else last = mid;
        }
        if (!(first - 1 >= 0 && nums[first - 1] == target)) return -1;
        return first - 1;
    }
}
posted @ 2022-03-24 17:08  wuzu  阅读(49)  评论(0编辑  收藏  举报