二分查找法技巧

基本二分法

    private int findFirst(int[] nums, int target) {
        int low = 0;
        int high = nums.length - 1; // 闭区间
        while (low <= high) { // 带等号
            int mid = (low + high) >>> 1;
            if (nums[mid] > target) {
                high = mid - 1;
            } else if (nums[mid] < target) {
                low = mid + 1;
            } else {
            // 判断左边界,变高位
            	return mid
            }
        }
        return -1;
    }

左边界二分法,在找到情况下,找到最左边的值

    private int findFirst(int[] nums, int target) {
        int low = 0;
        int high = nums.length - 1;
        while (low <= high) {
            int mid = (low + high) >>> 1;
            if (nums[mid] > target) {
                high = mid - 1;
            } else if (nums[mid] < target) {
                low = mid + 1;
            } else {
            // 判断左边界,变高位
                if ((mid == 0) || (nums[mid - 1] != target)) {
                    return mid;
                } else {
                    high = mid - 1;
                }
            }
        }
        return -1;
    }

作者:Fancier
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/jian-dan-de-er-fen-cha-zhao-jie-fa-tong-su-yi-dong/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

右边界二分法,在找到的情况下找到最右边的值

private int findLast(int[] nums, int target) {
        int low = 0;
        int high = nums.length - 1;
        while (low <= high) {
            int mid = (low + high) >>> 1;
            if (nums[mid] > target) {
                high = mid - 1;
            } else if (nums[mid] < target) {
                low = mid + 1;
            } else {
            	// 判断右边界,变低位
                if ((mid == nums.length - 1) || (nums[mid + 1] != target)) {
                    return mid;
                } else {
                    low = mid + 1;
                }
            }
        }
        return -1;
    }

作者:Fancier
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/jian-dan-de-er-fen-cha-zhao-jie-fa-tong-su-yi-dong/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

拓展:在找不到目标值的情况下,如何获得目标的上界和下界

在折半插入排序的时候,需要用二分法查到待插入的位置。用的是闭区间折半查找法,最后数据被插到了end+1位置。不过在前面判断的时候,mid值相等的时候被归到了右侧:

def bin_search(nums, target):
    size = len(nums)

    start = 0
    end = size - 1

    while start <= end:
        mid = start + (end - start) // 2
        if nums[mid] <= target: # 相等的时候将其排除在左侧,能保证找到右边界
            start = mid + 1
        else:
            end = mid - 1

    return [end, end + 1] # 最后end+1 位置一定是右边界
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章