Easy
题目描述
我们正在玩一个猜数字游戏,游戏规则如下:
我从 1 到 n 之间选择一个数字。你来猜我选的是哪个数字(我选的数字在整个游戏过程中保持不变)。
每当你猜错时,我会告诉你你猜的数字比我选的数字是大了还是小了。
你可以通过调用一个预先定义的接口 int guess(int num) 来获取猜测结果,返回值一共有 3 种可能的情况(-1,1 或 0):
- -1:你猜的数字比我选的数字大 (即
num > pick) - 1:你猜的数字比我选的数字小 (即
num < pick) - 0:你猜的数字和我选的数字一样 (即
num == pick)
返回我选的数字。
示例 1:
输入:n = 10, pick = 6
输出:6
示例 2:
输入:n = 1, pick = 1
输出:1
示例 3:
输入:n = 2, pick = 1
输出:1
提示:
1 <= n <= 2^31 - 11 <= pick <= n
解题思路
这是一道经典的二分查找问题。我们需要在 1 到 n 的范围内找到目标数字。
解题思路:
由于题目提供了 guess() API,可以告诉我们当前猜测的数字与目标数字的大小关系,这为二分查找提供了完美的条件。
初始化边界:设置左边界
left = 1,右边界right = n二分搜索过程:
- 计算中点
mid = left + (right - left) / 2,避免整数溢出 - 调用
guess(mid)获取结果 - 根据返回值调整搜索范围:
- 返回 -1:说明 mid 太大,目标在左半部分,更新
right = mid - 1 - 返回 1:说明 mid 太小,目标在右半部分,更新
left = mid + 1 - 返回 0:找到目标,直接返回 mid
- 返回 -1:说明 mid 太大,目标在左半部分,更新
- 计算中点
时间复杂度优化:每次查找都能排除一半的搜索空间,效率很高
这种方法保证了在最坏情况下也只需要 O(log n) 次猜测就能找到答案。
代码实现
class Solution {
public:
int guessNumber(int n) {
int left = 1, right = n;
while (left <= right) {
int mid = left + (right - left) / 2;
int result = guess(mid);
if (result == 0) {
return mid;
} else if (result == -1) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
};
class Solution:
def guessNumber(self, n: int) -> int:
left, right = 1, n
while left <= right:
mid = left + (right - left) // 2
result = guess(mid)
if result == 0:
return mid
elif result == -1:
right = mid - 1
else:
left = mid + 1
return -1
public class Solution : GuessGame {
public int GuessNumber(int n) {
int left = 1, right = n;
while (left <= right) {
int mid = left + (right - left) / 2;
int result = guess(mid);
if (result == 0) {
return mid;
} else if (result == -1) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
}
var guessNumber = function(n) {
let left = 1;
let right = n;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
let result = guess(mid);
if (result === 0) {
return mid;
} else if (result === 1) {
left = mid + 1;
} else {
right = mid - 1;
}
}
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(log n) | 二分查找,每次排除一半搜索空间 |
| 空间复杂度 | O(1) | 只使用常数级别的额外空间 |
相关题目
. First Bad Version (Easy)
. Guess Number Higher or Lower II (Medium)
. Find K Closest Elements (Medium)