1535. Find the Winner of an Array Game
Problem Description
You're given an array arr
of distinct integers and an integer k
. A game is played with the following rules:
- Start with the first two elements of the array (
arr[0]
andarr[1]
) - In each round, compare these two elements:
- The larger integer wins and stays at position 0
- The smaller integer moves to the end of the array
- The game continues with the winner at position 0 facing the next element (now at position 1)
- The game ends when an integer wins
k
consecutive rounds
Your task is to find which integer will win the game.
For example, if arr = [2, 1, 3, 5, 4, 6, 7]
and k = 2
:
- Round 1: Compare 2 and 1 → 2 wins (1 win for 2), array becomes
[2, 3, 5, 4, 6, 7, 1]
- Round 2: Compare 2 and 3 → 3 wins (1 win for 3), array becomes
[3, 5, 4, 6, 7, 1, 2]
- Round 3: Compare 3 and 5 → 5 wins (1 win for 5), array becomes
[5, 4, 6, 7, 1, 2, 3]
- Round 4: Compare 5 and 4 → 5 wins (2 wins for 5)
- Since 5 has won 2 consecutive rounds, the game ends and 5 is the winner
The problem guarantees that there will always be a winner.
Intuition
The key insight is recognizing that we don't actually need to simulate moving elements to the end of the array. Let's think about what really happens during the game:
When two elements compare, the winner stays at position 0 and faces the next element. The loser goes to the end, but here's the crucial observation: once an element loses, it can only win again if it eventually faces all other elements and beats them all. This means it would need to beat the current champion who has been winning.
Consider what happens as the game progresses:
- The winner at position 0 keeps facing new challengers one by one
- Each element in the array gets exactly one chance to challenge the current champion (except for the initial element at position 0)
- If we've gone through all
n-1
other elements without anyone winningk
times, the current champion must be the maximum element of the array
This leads to an important realization: the maximum element of the array will eventually win if the game goes on long enough, because it can never lose to any other element.
Therefore, we have two scenarios:
- Some element wins
k
consecutive rounds before we go through the entire array - We go through the entire array without anyone winning
k
times, in which case the maximum element must be the winner
This means we can simply iterate through the array once, keeping track of:
- The current "champion" (the element that would be at position 0)
- How many consecutive wins the current champion has
If the champion reaches k
wins, they're our answer. Otherwise, after going through all elements, the current champion (which would be the maximum element) is our answer.
Solution Approach
Based on our intuition, we can implement a simple linear scan without actually simulating the array rotations:
-
Initialize tracking variables:
mx
: The current champion (initiallyarr[0]
)cnt
: The consecutive win count for the current champion (initially 0)
-
Iterate through the array starting from index 1:
- For each element
x
inarr[1:]
:- Compare with current champion:
- If
mx < x
: The challenger wins- Update
mx = x
(new champion) - Reset
cnt = 1
(first win for new champion)
- Update
- If
mx >= x
: The champion wins- Increment
cnt += 1
(another consecutive win)
- Increment
- If
- Check winning condition:
- If
cnt == k
: We found our winner, break early
- If
- Compare with current champion:
- For each element
-
Return the champion
mx
The beauty of this approach is that even if we iterate through all n-1
elements without anyone achieving k
consecutive wins, the variable mx
will hold the maximum element of the array, which is guaranteed to be the eventual winner.
Why this works:
- Each element gets exactly one chance to challenge the current champion during our iteration
- If an element becomes the new champion, it faces all subsequent elements in order
- If we complete the iteration without reaching
k
wins, the current champion has already beaten all other elements at least once, making it the maximum element - The maximum element will continue winning indefinitely if the game continues
Time Complexity: O(n)
where n
is the length of the array - we iterate through the array at most once.
Space Complexity: O(1)
- we only use a constant amount of extra space for tracking variables.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example with arr = [3, 2, 1, 4]
and k = 2
:
Initial Setup:
mx = 3
(first element becomes initial champion)cnt = 0
(no wins yet)
Iteration 1: Compare 3 vs 2
- Since
mx (3) > 2
, the champion wins cnt = 1
(first win for 3)- Check:
cnt (1) < k (2)
, continue
Iteration 2: Compare 3 vs 1
- Since
mx (3) > 1
, the champion wins again cnt = 2
(second consecutive win for 3)- Check:
cnt (2) == k (2)
, we found our winner! - Return 3
Let's verify this matches the actual game simulation:
- Round 1: [3, 2, 1, 4] → 3 beats 2 → [3, 1, 4, 2]
- Round 2: [3, 1, 4, 2] → 3 beats 1 → [3, 4, 2, 1]
- 3 has won 2 consecutive rounds, so 3 wins!
Another example with arr = [1, 5, 2, 3]
and k = 3
:
Initial Setup:
mx = 1
(first element)cnt = 0
Iteration 1: Compare 1 vs 5
- Since
mx (1) < 5
, challenger wins mx = 5
(new champion)cnt = 1
(first win for 5)- Check:
cnt (1) < k (3)
, continue
Iteration 2: Compare 5 vs 2
- Since
mx (5) > 2
, champion wins cnt = 2
(second consecutive win for 5)- Check:
cnt (2) < k (3)
, continue
Iteration 3: Compare 5 vs 3
- Since
mx (5) > 3
, champion wins cnt = 3
(third consecutive win for 5)- Check:
cnt (3) == k (3)
, we found our winner! - Return 5
Note how we never needed to actually move elements to the end of the array - we just tracked who the current champion is and their win streak!
Solution Implementation
1class Solution:
2 def getWinner(self, arr: List[int], k: int) -> int:
3 """
4 Find the winner after k consecutive wins in an array game.
5
6 The game simulates comparing the first two elements, where the larger one wins
7 and stays at position 0, while the smaller one moves to the end of the array.
8 The winner is the first element to achieve k consecutive wins.
9
10 Args:
11 arr: List of distinct integers
12 k: Number of consecutive wins needed
13
14 Returns:
15 The integer that wins k consecutive rounds
16 """
17 # Initialize the current maximum (winner) as the first element
18 current_winner = arr[0]
19
20 # Track consecutive wins for the current winner
21 consecutive_wins = 0
22
23 # Iterate through remaining elements in the array
24 for current_element in arr[1:]:
25 if current_winner < current_element:
26 # New winner found, update winner and reset win count
27 current_winner = current_element
28 consecutive_wins = 1
29 else:
30 # Current winner wins again, increment win count
31 consecutive_wins += 1
32
33 # Check if current winner has achieved k consecutive wins
34 if consecutive_wins == k:
35 break
36
37 # Return the winner (handles both early termination and max element cases)
38 return current_winner
39
1class Solution {
2 public int getWinner(int[] arr, int k) {
3 // Initialize the current maximum (winner) as the first element
4 int currentWinner = arr[0];
5
6 // Track consecutive wins count, starting from 0
7 int consecutiveWins = 0;
8
9 // Iterate through the array starting from the second element
10 for (int i = 1; i < arr.length; i++) {
11 if (currentWinner < arr[i]) {
12 // If current element is greater, it becomes the new winner
13 currentWinner = arr[i];
14 // Reset consecutive wins to 1 (first win for new winner)
15 consecutiveWins = 1;
16 } else {
17 // Current winner beats arr[i], increment win count
18 consecutiveWins++;
19 }
20
21 // Check if current winner has achieved k consecutive wins
22 if (consecutiveWins == k) {
23 // Early termination when k wins are reached
24 break;
25 }
26 }
27
28 // Return the winner (either achieved k wins or is the maximum element)
29 return currentWinner;
30 }
31}
32
1class Solution {
2public:
3 int getWinner(vector<int>& arr, int k) {
4 // Initialize the current winner as the first element
5 int currentWinner = arr[0];
6 // Track consecutive wins for the current winner
7 int consecutiveWins = 0;
8
9 // Iterate through the array starting from the second element
10 for (int i = 1; i < arr.size(); ++i) {
11 if (currentWinner < arr[i]) {
12 // arr[i] beats the current winner, so it becomes the new winner
13 currentWinner = arr[i];
14 consecutiveWins = 1; // Reset win count to 1 for the new winner
15 } else {
16 // Current winner defeats arr[i], increment win count
17 ++consecutiveWins;
18 }
19
20 // Check if current winner has achieved k consecutive wins
21 if (consecutiveWins == k) {
22 break; // Early termination as we found our answer
23 }
24 }
25
26 // Return the winner (either achieved k wins or is the maximum element)
27 return currentWinner;
28 }
29};
30
1/**
2 * Finds the winner after k consecutive wins in a game where elements compete
3 * @param arr - Array of numbers representing players
4 * @param k - Number of consecutive wins needed to determine the winner
5 * @returns The winning number
6 */
7function getWinner(arr: number[], k: number): number {
8 // Track the current maximum (winner) element
9 let currentMax: number = arr[0];
10
11 // Track consecutive win count for the current maximum
12 let consecutiveWins: number = 0;
13
14 // Iterate through remaining elements starting from index 1
15 for (const currentElement of arr.slice(1)) {
16 if (currentMax < currentElement) {
17 // New element wins, becomes the new maximum
18 currentMax = currentElement;
19 consecutiveWins = 1;
20 } else {
21 // Current maximum wins again, increment win count
22 consecutiveWins++;
23 }
24
25 // Check if we've reached k consecutive wins
26 if (consecutiveWins === k) {
27 break;
28 }
29 }
30
31 return currentMax;
32}
33
Time and Space Complexity
Time Complexity: O(n)
where n
is the length of the input array arr
.
The algorithm iterates through the array once using a for loop that goes through arr[1:]
, which means it processes at most n-1
elements. Each iteration performs constant time operations (comparisons and variable updates). Even though there's a break statement when cnt == k
, in the worst case scenario (when k
is very large or when we need to find the maximum element), we still traverse the entire array. Therefore, the time complexity is linear with respect to the size of the input array.
Space Complexity: O(1)
The algorithm uses only a constant amount of extra space regardless of the input size. It maintains just two variables: mx
(to store the current winner) and cnt
(to count consecutive wins). The iteration through arr[1:]
doesn't create a new array in Python - it's just a slice that provides a view of the original array. No additional data structures are used that scale with the input size.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Misunderstanding When k > n-1
The Issue:
A common mistake is thinking we need to simulate the actual circular rotation of the array when k
is larger than n-1
. Developers might implement complex logic to handle the case where elements cycle back to the front of the array after being moved to the end.
Why It's Wrong:
Consider arr = [3, 2, 1]
with k = 10
. After the first pass:
- 3 beats 2 (1 win)
- 3 beats 1 (2 wins)
- Now 3 is the maximum element
Even though k = 10 > 2
, we don't need to continue simulating. Once an element has beaten all others (becoming the maximum), it will continue winning indefinitely. The maximum element will never lose, so it's guaranteed to reach k
consecutive wins.
The Solution: The provided code handles this elegantly by:
- Finding the maximum element through one pass
- If no element reaches
k
wins during the pass, the current winner is the maximum - The maximum element is automatically returned as the winner
Pitfall 2: Off-by-One Error in Initial Win Count
The Issue: When implementing the solution, developers might incorrectly initialize the win count:
# Incorrect approach current_winner = arr[0] consecutive_wins = 1 # Wrong! arr[0] hasn't won anything yet for current_element in arr[1:]: if current_winner < current_element: current_winner = current_element consecutive_wins = 1 else: consecutive_wins += 1
Why It's Wrong:
This gives arr[0]
credit for a win it hasn't earned yet. If k = 1
and arr[0]
is larger than arr[1]
, this would incorrectly return arr[0]
after just one comparison instead of requiring it to actually win one round.
The Solution:
Always initialize consecutive_wins = 0
because the first element hasn't competed yet. It only gets wins by actually beating other elements in comparisons.
Pitfall 3: Attempting to Actually Rotate the Array
The Issue: Some implementations try to physically manipulate the array:
# Inefficient approach while True: if arr[0] > arr[1]: winner = arr[0] loser = arr.pop(1) arr.append(loser) wins += 1 else: winner = arr[1] loser = arr.pop(0) arr.append(loser) arr[0] = winner wins = 1 if wins == k: return winner
Why It's Wrong:
- Time complexity becomes O(n*k) in worst case due to array manipulations
- Space complexity increases due to array modifications
- Unnecessarily complex and prone to bugs
The Solution: The linear scan approach simulates the game conceptually without actually moving elements. Each element gets exactly one chance to challenge the current champion, which perfectly mirrors what would happen in the actual game rotation.
Which of the two traversal algorithms (BFS and DFS) can be used to find whether two nodes are connected?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!