二分查找法技巧

基本二分法

    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 位置一定是右邊界
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章