You are given an integer maxChoosableInteger
and a desired total
. You and an opponent take turns picking numbers from 1
to maxChoosableInteger
(inclusive) without replacement. The player who first reaches or exceeds the desired total
wins. Assuming both players play optimally, return true
if the first player can guarantee a win, otherwise return false
.
maxChoosableInteger
be larger than total
?
maxChoosableInteger
can be larger or smaller than total
.1 <= maxChoosableInteger <= 20
0 <= desiredTotal <= 300
total <= 0
, the player cannot win.maxChoosableInteger >= total
, the first player can directly choose total
and win.def canIWin(maxChoosableInteger, desiredTotal):
if desiredTotal <= 0:
return True
if sum(range(1, maxChoosableInteger + 1)) < desiredTotal:
return False
memo = {}
def can_win(remaining, chosen):
if remaining <= 0:
return False
if chosen in memo:
return memo[chosen]
for i in range(1, maxChoosableInteger + 1):
current_mask = 1 << i
if chosen & current_mask == 0:
if not can_win(remaining - i, chosen | current_mask):
memo[chosen] = True
return True
memo[chosen] = False
return False
return can_win(desiredTotal, 0)
# Example usage:
maxChoosableInteger = 10
desiredTotal = 11
print(canIWin(maxChoosableInteger, desiredTotal)) # Output: False
The time complexity of the solution can be analyzed as follows:
2^maxChoosableInteger
, which is 2^20
in the worst case.maxChoosableInteger
choices.Therefore, the time complexity is O(2^n * n)
, where n
is maxChoosableInteger
.
The space complexity is primarily dictated by the memoization table holding up to 2^n
entries, making it O(2^n)
.
Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?