在问 · 算法题解

374. 猜数字大小

题目描述

系统事先从 1 到 n 中选定一个整数 pick,整个过程中它不会变。你的任务是找出这个数。

可以调用现成的接口 guess(num) 来试探。它返回 -1 表示猜大了(num > pick);返回 1 表示猜小了(num < pick);返回 0 表示猜对了。

函数只接收 n,返回 pick 的值。示例中给出的 pick 只用于说明答案。

示例 1
输入:n = 10, pick = 6
输出:6
示例 2
输入:n = 1, pick = 1
输出:1

解释:只有一个候选数 1。

示例 3
输入:n = 2, pick = 1
输出:1

数据范围

  • 1 <= n <= 2^31 - 1
  • 1 <= pick <= n

解题思路

经典闭区间二分。候选区间 [lo, hi] 一开始是 [1, n]。每次猜中点 mid:返回 0 就是答案;返回 1 说明 pick 比 mid 大,lo = mid + 1;返回 -1 说明 pick 比 mid 小,hi = mid - 1。

为什么正确

pick 始终在 [lo, hi] 中。

复杂度分析

至多调用 guess 约 log2(n) + 1 次,时间 O(log n),空间 O(1)。

易错点

返回值的含义容易弄反:-1 是“你猜的数太大”,要往左找。另外 n 可达 2^31 - 1,(lo + hi) 在 32 位整数中会溢出,要写 lo + (hi - lo) // 2。

参考代码

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

class Solution:
    def guessNumber(self, n: int) -> int:
        lo, hi = 1, n
        while lo <= hi:
            mid = lo + (hi - lo) // 2
            res = guess(mid)
            if res == 0:
                return mid
            if res == 1:
                lo = mid + 1
            else:
                hi = mid - 1
        return -1

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

二分查找 专题的其他题目

查看 二分查找 全部题目 →