Skip to content

Files

62 lines (49 loc) · 2.24 KB

README.md

File metadata and controls

62 lines (49 loc) · 2.24 KB

二分查找

二分的本质并非“单调性”,而是“边界”,只要找到某种性质,使得整个区间一分为二,那么就可以用二分把边界点二分出来。

算法模板

模板 1

boolean check(int x) {
}

int search(int left, int right) {
    while (left < right) {
        int mid = (left + right) >> 1;
        if (check(mid)) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return left;
}

模板 2

boolean check(int x) {
}

int search(int left, int right) {
    while (left < right) {
        int mid = (left + right + 1) >> 1;
        if (check(mid)) {
            left = mid;
        } else {
            right = mid - 1;
        }
    }
    return left;
}

做二分题目时,可以按照以下套路:

  1. 写出循环条件 l e f t < r i g h t
  2. 循环体内,不妨先写 m i d = l e f t + r i g h t 2
  3. 根据具体题目,实现 c h e c k ( ) 函数(有时很简单的逻辑,可以不定义 c h e c k ),想一下究竟要用 r i g h t = m i d (模板 1 ) 还是 l e f t = m i d (模板 2 );     - 如果 r i g h t = m i d ,那么写出 else 语句 l e f t = m i d + 1 ,并且不需要更改 mid 的计算,即保持 m i d = l e f t + r i g h t 2 ;     - 如果 l e f t = m i d ,那么写出 else 语句 r i g h t = m i d 1 ,并且在 m i d 计算时补充 +1,即 m i d = l e f t + r i g h t + 1 2
  4. 循环结束时,$left$ 与 r i g h t 相等。

注意,这两个模板的优点是始终保持答案位于二分区间内,二分结束条件对应的值恰好在答案所处的位置。 对于可能无解的情况,只要判断二分结束后的 l e f t 或者 r i g h t 是否满足题意即可。

例题