TL;DR
Binary search over [1, n] using the guess API as the comparator β O(log n) time, O(1) space.
Approach 1 β Brute force (guess every number)
Try 1, then 2, then 3, β¦ until the API answers 0.
# The guess API is already defined for you.
# def guess(num: int) -> int:
class Solution:
def guessNumber(self, n: int) -> int:
for num in range(1, n + 1):
if guess(num) == 0:
return num
return n # unreachable: the pick is guaranteed to exist
Time O(n) API calls, space O(1). With n up to 2^31 - 1 β 2.1 billion, a worst-case pick near n means billions of calls β hopeless.
Approach 2 β Binary search on the range
The insight: the APIβs three-way answer is exactly the comparison binary search needs. The candidates 1..n form a sorted range, and each call to guess(mid) tells us whether the secret is below, above, or at mid β so every call halves the remaining range. Binary search is the classical algorithm that repeatedly halves a monotone search space with one comparison per step.
# The guess API is already defined for you.
# def guess(num: int) -> int:
class Solution:
def guessNumber(self, n: int) -> int:
lo, hi = 1, n
while lo <= hi:
mid = lo + (hi - lo) // 2
verdict = guess(mid)
if verdict == 0:
return mid
if verdict == -1: # secret is lower
hi = mid - 1
else: # secret is higher
lo = mid + 1
return -1 # unreachable: the pick always exists in [1, n]
Walkthrough on n = 10, secret pick = 6:
lo=1, hi=10 β mid=5, guess(5)=1 (secret higher) β lo=6.
lo=6, hi=10 β mid=8, guess(8)=-1 (secret lower) β hi=7.
lo=6, hi=7 β mid=6, guess(6)=0 β return 6. β
Three calls instead of six. Time O(log n) β about 31 calls even at n = 2^31 - 1. Space O(1).
Approach 3 β Recursive binary search
The insight: the same halving reads naturally as βguess the middle of the current range, then recurse into the half the API points toβ β the divide-and-conquer phrasing of the identical algorithm.
# The guess API is already defined for you.
# def guess(num: int) -> int:
class Solution:
def guessNumber(self, n: int) -> int:
def go(lo: int, hi: int) -> int:
mid = lo + (hi - lo) // 2
verdict = guess(mid)
if verdict == 0:
return mid
if verdict == -1:
return go(lo, mid - 1)
return go(mid + 1, hi)
return go(1, n)
Walkthrough on n = 2, secret pick = 1:
go(1, 2): mid=1, guess(1)=0 β return 1. β
Time O(log n), space O(log n) recursion stack β same call count as the iterative version, slightly worse space; know both formulations.
Common pitfalls
- Reversing the APIβs meaning:
-1 means your guess is too high (secret is lower), not βgo higherβ. Misreading it sends the search the wrong way and the loop exits without finding the pick.
- In fixed-width-integer languages,
(lo + hi) / 2 overflows when hi is near 2^31 - 1 β this problemβs bounds are chosen to punish exactly that. Write lo + (hi - lo) // 2.
- Shrinking to
hi = mid / lo = mid instead of stepping past mid β infinite loop on a two-value range.
- Starting the range at
0: the secret is in [1, n], and wasting a guess on 0 both misreads the problem and can loop when n = 1.
Pattern takeaway
Binary search doesnβt need an array β it needs an ordered range of candidates and an oracle that says βtoo low / too high / foundβ. Any time an API, a predicate, or a computation gives you that three-way (or even two-way) verdict over a monotone range, you can halve your way to the answer in logarithmic steps.