在问 · 算法题解

704. 二分查找

题目描述

输入一个按升序排列、元素互不相同的整数数组 nums,以及目标值 target。

如果 target 在数组中,返回它的下标(从 0 开始);否则返回 -1。

算法的时间复杂度必须是 O(log n)。

示例 1
输入:nums = [-1,0,3,5,9,12], target = 9
输出:4

解释:9 位于下标 4。

示例 2
输入:nums = [-1,0,3,5,9,12], target = 2
输出:-1

解释:数组里没有 2。

数据范围

  • nums 中的元素互不相同。
  • n 在 [1, 10000] 之间。
  • nums 的每个元素在 [-9999, 9999] 之间。

解题思路

维护闭区间 [lo, hi] 作为 target 可能出现的范围。每次看中点:等于就返回;nums[mid] 小于 target,说明 mid 及左边都太小,lo = mid + 1;否则 mid 及右边都太大,hi = mid - 1。区间为空就说明不存在。

为什么正确

若 target 存在,它的下标一定在闭区间 [lo, hi] 中。

复杂度分析

时间 O(log n),空间 O(1)。

易错点

闭区间写法循环条件要用 lo <= hi,收缩时用 mid ± 1;混用 lo < hi 或 hi = mid 会漏掉最后一个元素或死循环。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        lo, hi = 0, len(nums) - 1
        while lo <= hi:
            mid = (lo + hi) // 2
            if nums[mid] == target:
                return mid
            if nums[mid] < target:
                lo = mid + 1
            else:
                hi = mid - 1
        return -1

载入编辑器,自己跑一遍 →

二分查找 专题的其他题目

查看 二分查找 全部题目 →