# 经典二分查找

返回的 lo 即为 target 应该出现的位置

  • 如果 target 存在,则返回 target 的位置
  • 如果 target 不存在,则返回 target 应该插入的位置
public static int binarySearch(int[] nums, int target) {
    int lo = 0, hi = nums.length - 1;
    while (lo <= hi) {
        int mid = lo + ((hi - lo) >> 1);
        if (nums[mid] == target) return mid;
        else if (nums[mid] > target) hi = mid - 1;
        else if (nums[mid] < target) lo = mid + 1;
    }
    return lo;
}
1
2
3
4
5
6
7
8
9
10

# 重复元素 + 查找左右边界

  • 左边界或者说第一个满足条件的元素,返回 lo
  • 右边界或者说最后一个满足条件的元素,返回 hi
// 左边界
public static int binarySearch(int[] nums, int target) {
    int lo = 0, hi = nums.length - 1;
    while (lo <= hi) {
        int mid = lo + ((hi - lo) >> 1);
        if (nums[mid] == target) hi = mid - 1;
        else if (nums[mid] > target) hi = mid - 1;
        else if (nums[mid] < target) lo = mid + 1;
    }
    return lo;
}

// 右边界
public static int binarySearch(int[] nums, int target) {
    int lo = 0, hi = nums.length - 1;
    while (lo <= hi) {
        int mid = lo + ((hi - lo) >> 1);
        if (nums[mid] == target) lo = mid + 1;
        else if (nums[mid] > target) hi = mid - 1;
        else if (nums[mid] < target) lo = mid + 1;
    }
    return hi;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 二分查找抽象

二分查找并不是只能用于搜索有序数组,当搜索空间有序的时候,就可以通过二分搜索「剪枝」,大幅提升效率

本质:将二分查找的判断条件进行抽象

public static int binarySearch(int[] nums) {
    int lo = 0, hi = nums.length - 1;
    while (lo <= hi) {
        int mid = lo + ((hi - lo) >> 1);
        checkCondition(nums[mid]);
        if (正好) return mid;
        else if (需要向左搜索) hi = mid - 1;
        else if (需要向右搜索) lo = mid + 1;
    }
    return lo;
}

// 寻找最小的满足条件
public static int binarySearch(int[] nums) {
    int lo = 0, hi = nums.length - 1;
    while (lo <= hi) {
        int mid = lo + ((hi - lo) >> 1);
        checkCondition(nums[mid]);
        if (满足条件) {
            // 等效于 nums[mid] >= target
            hi = mid - 1;
        }
        else if (还不足) {
            // 等效于 nums[mid] < target
            lo = mid + 1;
        }
    }
    return lo;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Last Updated: 9/24/2020, 8:12:29 AM