374. Guess Number Higher Or Lower - Explanation
Description
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)
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Binary Search - Efficiently searching a sorted range by repeatedly halving the search space based on comparison feedback
1. Linear Search
Intuition
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.
Algorithm
- Iterate through numbers from
1ton. - For each number, call the
guessAPI. - If
guessreturns0, the current number is correct; return it. - Continue until the answer is found.
# 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 numTime & Space Complexity
- Time complexity:
- Space complexity:
2. Binary Search
Intuition
Since 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.
Algorithm
- Initialize two pointers:
l = 1andr = n. - Calculate the middle value
m = (l + r) / 2. - Call
guess(m):- If it returns
0, we found the number; returnm. - If it returns
1(number is higher), setl = m + 1. - If it returns
-1(number is lower), setr = m - 1.
- If it returns
- Repeat until the number is found.
# 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 mTime & Space Complexity
- Time complexity:
- Space complexity:
3. Ternary Search
Intuition
Ternary 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.
Algorithm
- Initialize two pointers:
l = 1andr = n. - Calculate two midpoints:
m1 = l + (r - l) / 3andm2 = r - (r - l) / 3. - Check
guess(m1)andguess(m2):- If either returns
0, return that midpoint. - If both results sum to
0(one is1, other is-1), the answer lies betweenm1andm2; update both bounds. - If
guess(m1)is-1, the answer is belowm1; setr = m1 - 1. - Otherwise, the answer is above
m2; setl = m2 + 1.
- If either returns
- Repeat until the number is found.
# 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 + 1Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Misinterpreting the guess() API Return Values
The 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.
Integer Overflow When Computing the Midpoint
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.
Sign in to join the discussion