We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I will tell you whether the number I picked is higher or lower than your guess.
You call a pre-defined API int guess(int num), which returns three possible results:
0: your guess is equal to the number I picked (i.e. num == pick).-1: Your guess is higher than the number I picked (i.e. num > pick).1: Your guess is lower than the number I picked (i.e. num < pick).Return the number that I picked.
Example 1:
Input: n = 5, pick = 3
Output: 3Example 2:
Input: n = 15, pick = 10
Output: 10Example 3:
Input: n = 1, pick = 1
Output: 1Constraints:
1 <= pick <= n <= ((2^31)-1)Before attempting this problem, you should be comfortable with:
The simplest approach is to try every number from 1 to n until we find the correct one. Each guess tells us whether we hit the target. While guaranteed to work, this method is slow for large n since we might need to check every single number.
1 to n.guess API.guess returns 0, the current number is correct; return it.# The guess API is already defined for you.
# @param num, your guess
# @return -1 if num is higher than the picked number
# 1 if num is lower than the picked number
# otherwise return 0
# 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 numSince the numbers from 1 to n are sorted, we can use binary search to find the target efficiently. The guess API tells us whether to search higher or lower, which is exactly the feedback binary search needs to halve the search space with each guess.
l = 1 and r = n.m = (l + r) / 2.guess(m):0, we found the number; return m.1 (number is higher), set l = m + 1.-1 (number is lower), set r = m - 1.# The guess API is already defined for you.
# @param num, your guess
# @return -1 if num is higher than the picked number
# 1 if num is lower than the picked number
# otherwise return 0
# def guess(num: int) -> int:
class Solution:
def guessNumber(self, n: int) -> int:
l, r = 1, n
while True:
m = (l + r) // 2
res = guess(m)
if res > 0:
l = m + 1
elif res < 0:
r = m - 1
else:
return mTernary search divides the search space into three parts instead of two. We pick two midpoints and use the guess API on both. Based on the results, we can eliminate either one-third or two-thirds of the search space. While this approach works, it does not improve on binary search for this problem since we need more API calls per iteration.
l = 1 and r = n.m1 = l + (r - l) / 3 and m2 = r - (r - l) / 3.guess(m1) and guess(m2):0, return that midpoint.0 (one is 1, other is -1), the answer lies between m1 and m2; update both bounds.guess(m1) is -1, the answer is below m1; set r = m1 - 1.m2; set l = m2 + 1.# The guess API is already defined for you.
# @param num, your guess
# @return -1 if num is higher than the picked number
# 1 if num is lower than the picked number
# otherwise return 0
# def guess(num: int) -> int:
class Solution:
def guessNumber(self, n: int) -> int:
l, r = 1, n
while True:
m1 = l + (r - l) // 3
m2 = r - (r - l) // 3
if guess(m1) == 0:
return m1
if guess(m2) == 0:
return m2
if guess(m1) + guess(m2) == 0:
l = m1 + 1
r = m2 - 1
elif guess(m1) == -1:
r = m1 - 1
else:
l = m2 + 1The guess() API returns -1 when your guess is higher than the picked number and 1 when your guess is lower. This is counterintuitive since many people expect positive to mean "go higher." Mixing up these return values causes the binary search to move in the wrong direction, leading to infinite loops or incorrect results.
Calculating the midpoint as (l + r) / 2 can cause integer overflow when l and r are both large values close to the maximum integer. The safe approach is to use l + (r - l) / 2, which avoids adding two large numbers together and prevents overflow in languages with fixed-size integers like Java, C++, and Go.