There are n
friends that are playing a game. The friends are sitting in a circle and are numbered from 1
to n
in clockwise order. More formally, moving clockwise from the ith
friend brings you to the (i+1)th
friend for 1 <= i < n
, and moving clockwise from the nth
friend brings you to the 1st
friend.
The rules of the game are as follows:
1st
friend.k
friends in the clockwise direction including the friend you started at. The counting wraps around the circle and may count some friends more than once.2
starting from the friend immediately clockwise of the friend who just lost and repeat.Given the number of friends, n
, and an integer k
, return the winner of the game.
Example 1:
Input: n = 5, k = 2 Output: 3 Explanation: Here are the steps of the game: 1) Start at friend 1. 2) Count 2 friends clockwise, which are friends 1 and 2. 3) Friend 2 leaves the circle. Next start is friend 3. 4) Count 2 friends clockwise, which are friends 3 and 4. 5) Friend 4 leaves the circle. Next start is friend 5. 6) Count 2 friends clockwise, which are friends 5 and 1. 7) Friend 1 leaves the circle. Next start is friend 3. 8) Count 2 friends clockwise, which are friends 3 and 5. 9) Friend 5 leaves the circle. Only friend 3 is left, so they are the winner.
Example 2:
Input: n = 6, k = 5 Output: 1 Explanation: The friends leave in this order: 5, 4, 6, 2, 3. The winner is friend 1.
Constraints:
1 <= k <= n <= 500
Follow up:
Could you solve this problem in linear time with constant space?
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 simulates the game exactly as described. We start with all the players and eliminate them one by one according to the rules until only one player remains. That last player is declared the winner.
Here's how the algorithm would work step-by-step:
def find_the_winner_circular_game_brute_force(number_of_players, skip_value):
players = list(range(1, number_of_players + 1))
current_index = 0
while len(players) > 1:
# Adjust the index by the skip value and account for circularity
current_index = (current_index + skip_value - 1) % len(players)
# Eliminate the player at the calculated index
players.pop(current_index)
# The next player after the eliminated player becomes the new current player
# This is automatically handled because of the pop operation
# Return the last remaining player
return players[0]
The problem involves removing people in a circle until only one remains. The fastest way to solve this is by recognizing a pattern in how the winner changes as people are removed instead of directly simulating the removal process each time.
Here's how the algorithm would work step-by-step:
def find_the_winner(number_of_people, skip_count):
winner = 0
# Winner for n people can be derived from winner of n-1
for numberOfPeople in range(2, number_of_people + 1):
# This formula relates winner in current circle
# to winner in previous smaller circle
winner = (winner + skip_count) % numberOfPeople
# Winner index needs to be adjusted for 1-based indexing
return winner + 1
Case | How to Handle |
---|---|
n is 0 or negative | Return -1 or throw an exception, as a game with zero or negative players is invalid. |
k is 0 or negative | Return -1 or throw an exception, as a zero or negative step size is not meaningful in this game. |
n is 1 | Return 1 directly, as the first player automatically wins if there's only one player. |
k is 1 | Return n as all players are removed sequentially until only the last player is remaining. |
k is equal to n | Return n-1 as it eliminates the last player in the circle. |
k is greater than n | Handle the wrap-around logic by using the modulo operator (%) to correctly calculate the next player to eliminate after each round. |
Large n and k values potentially leading to integer overflow during intermediate calculations if using naive recursive approaches. | Implement the solution iteratively or use modular arithmetic with large data types to avoid overflow issues. |
Extremely large n, where representing all players explicitly in a list or array becomes memory intensive | Use the Josephus problem formula or its iterative equivalent, which is optimized for space complexity, instead of simulating the entire game. |