Alice and Bob continue their games with stones. There is a row of n stones, and each stone has an associated value. You are given an integer array stones
, where stones[i]
is the value of the ith
stone.
Alice and Bob take turns, with Alice starting first. On each turn, the player may remove any stone from stones
. The player who removes a stone loses if the sum of the values of all removed stones is divisible by 3
. Bob will win automatically if there are no remaining stones (even if it is Alice's turn).
Assuming both players play optimally, return true
if Alice wins and false
if Bob wins.
Example 1:
Input: stones = [2,1] Output: true Explanation: The game will be played as follows: - Turn 1: Alice can remove either stone. - Turn 2: Bob removes the remaining stone. The sum of the removed stones is 1 + 2 = 3 and is divisible by 3. Therefore, Bob loses and Alice wins the game.
Example 2:
Input: stones = [2] Output: false Explanation: Alice will remove the only stone, and the sum of the values on the removed stones is 2. Since all the stones are removed and the sum of values is not divisible by 3, Bob wins the game.
Example 3:
Input: stones = [5,1,2,4,3] Output: false Explanation: Bob will always win. One possible way for Bob to win is shown below: - Turn 1: Alice can remove the second stone with value 1. Sum of removed stones = 1. - Turn 2: Bob removes the fifth stone with value 3. Sum of removed stones = 1 + 3 = 4. - Turn 3: Alices removes the fourth stone with value 4. Sum of removed stones = 1 + 3 + 4 = 8. - Turn 4: Bob removes the third stone with value 2. Sum of removed stones = 1 + 3 + 4 + 2 = 10. - Turn 5: Alice removes the first stone with value 5. Sum of removed stones = 1 + 3 + 4 + 2 + 5 = 15. Alice loses the game because the sum of the removed stones (15) is divisible by 3. Bob wins the game.
Constraints:
1 <= stones.length <= 105
1 <= stones[i] <= 104
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to this game is to explore every possible move in every possible game state. We simulate every possible game from the beginning until one player wins, and then we determine who wins from the starting position. This ensures that we consider all possible scenarios and outcomes.
Here's how the algorithm would work step-by-step:
def stone_game_ix_brute_force(stones):
def can_win(current_stones, current_sum):
# If no stones are left, determine the winner based on the sum
if not current_stones:
return current_sum % 3 != 0
for index, stone in enumerate(current_stones):
# If the current sum is divisible by 3, the player loses
if (current_sum + stone) % 3 == 0:
continue
remaining_stones = current_stones[:index] + current_stones[index+1:]
# Recursively call the function for the next player's turn.
if not can_win(remaining_stones, current_sum + stone):
return True
return False
# This checks if Alice can win from the starting position
return can_win(stones, 0)
The core idea is to analyze the remainders of the stones when divided by 3. The player who can force a draw state for their opponent will win. We want to count how many stones have remainder 0, 1, and 2 when divided by 3, and based on those counts, determine the winner.
Here's how the algorithm would work step-by-step:
def stone_game_ix(stones): remainder_0_count = 0
remainder_1_count = 0
remainder_2_count = 0
for stone in stones:
if stone % 3 == 0:
remainder_0_count += 1
elif stone % 3 == 1:
remainder_1_count += 1
else:
remainder_2_count += 1
# Handle base cases where either remainder 1 or 2 stones are missing.
if remainder_1_count == 0 or remainder_2_count == 0:
if remainder_0_count % 2 == 0:
return False
return remainder_0_count > 0
# Analyze the difference between remainder 1 and 2 counts.
difference = abs(remainder_1_count - remainder_2_count)
#If diff is greater than 2, Alice always wins.
if difference > 2:
return True
#Check if remainder 0 stones lead to Alice winning.
if remainder_0_count > 0:
return True
#Otherwise, Bob wins.
return False
Case | How to Handle |
---|---|
Empty input array | Return False immediately as no moves are possible. |
Array with only one element | Return False immediately as the first player will always lose. |
All numbers in the array are divisible by 3 | If the number of elements is odd, Alice wins; otherwise, Bob wins. |
Array with all numbers leaving a remainder of 1 when divided by 3 | Compare the counts of numbers with remainder 1 and 2, Alice wins if count(1) > count(2) + 1 or count(2) > count(1). |
Array with all numbers leaving a remainder of 2 when divided by 3 | Compare the counts of numbers with remainder 1 and 2, Alice wins if count(1) > count(2) + 1 or count(2) > count(1). |
A large array with uneven distribution of remainders (1 and 2) | The solution's O(n) complexity should scale adequately for large arrays; analyze remainder distribution to predict winner. |
Integer overflow if summing very large numbers | The solution doesn't involve summing the numbers themselves, so overflow isn't a concern; only the counts are compared. |
Input array contains negative numbers | The problem description does not specify that the numbers should be non-negative; if so, the modulus operation must be handled carefully to always produce a number between 0 and 2. |