算法-二分搜索法

66 阅读1分钟

定义

二分法是在排序的数组中找到指定元素的算法。每次可以排除一半的剩余区间。算法时间复杂度O(logn),空间复杂度 O(logn)。

应用1: 找到目标元素/是否存在

这个是最简单的应用,因为无边界问题

private int findIndex(int[] sortedArr, int target) {
    int left = 0;
    int right = sortedArr.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (sortedArr[mid] == target) {
            return mid;
        } else if (sortedArr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}

应用2:寻找左右边界

左边界:假设 x 是不满足,o 是满足,现在需要寻找第一个满足的索引 x x x o o o o o

右边界:假设 x 是不满足,o 是满足,现在需要寻找最后一个满足的索引 o o o o o x x x

// x x x  o o o o o o
//        ^
public int findFistFit(char[] arr) {
    int left = 0;
    int right = arr.length - 1;
    while (left < right) {
        int mid = left + (right - left) / 2; // 偏左,所以左边的需要+1,不然可能死循环。
        if (fit(arr[mid])) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    if (fit(arr[left])) {
        return left;
    } else {
        // 全部不满足。
        return -1;
    }
}

// o o o o o x x x
//         ^
public int findLastFit(char[] arr) {
    int left = 0;
    int right = arr.length - 1;
    while (left < right) {
        int mid = left + (right + left + 1) / 2;
        if (fit(arr[mid])) {
            left = mid;
        } else {
            right = mid - 1;
        }
    }
    if (fit(arr[right])) {
        return right;
    } else {
        // 全部不满足。
        return -1;
    }
}

private boolean fit(char c) {
    return c == 'o';
}