Problem
Given an integer array arr
of distinct integers and an integer k
.
A game will be played between the first two elements of the array (i.e. arr[0]
and arr[1]
). In each round of the game, we compare arr[0]
with arr[1]
, the larger integer wins and remains at position 0
, and the smaller integer moves to the end of the array. The game ends when an integer wins k
consecutive rounds.
Return the integer which will win the game.
It is guaranteed that there will be a winner of the game.
Examples
Example 1:
Input: arr = [2,1,3,5,4,6,7], k = 2
Output: 5
Explanation: Let's see the rounds of the game:
Round | arr | winner | win_count
1 | [2,1,3,5,4,6,7] | 2 | 1
2 | [2,3,5,4,6,7,1] | 3 | 1
3 | [3,5,4,6,7,1,2] | 5 | 1
4 | [5,4,6,7,1,2,3] | 5 | 2
So we can see that 4 rounds will be played and 5 is the winner because it wins 2 consecutive games.
Example 2:
Input: arr = [3,2,1], k = 10
Output: 3
Explanation: 3 will win the first 10 rounds consecutively.
Solution
Method 1 - Simulation
To solve this problem, we need to simulate the game rounds, track the current winning streak, and check if any integer wins k
consecutive rounds.
Code
Java
public class Solution {
public int getWinner(int[] arr, int k) {
int n = arr.length;
int currentWinner = arr[0];
int winCount = 0;
for (int i = 1; i < n; i++) {
if (arr[i] > currentWinner) {
currentWinner = arr[i];
winCount = 1;
} else {
winCount++;
}
if (winCount == k) {
return currentWinner;
}
}
return currentWinner;
}
}
Python
def get_winner(arr, k):
n = len(arr)
current_winner = arr[0]
win_count = 0
for i in range(1, n):
if arr[i] > current_winner:
current_winner = arr[i]
win_count = 1
else:
win_count += 1
if win_count == k:
return current_winner
return current_winner
Complexity
- Time:
O(n)
- Space:
O(1)
Method 2 - Deque
We can use a Deque
(double-ended queue) for more efficient operations. Here is the improved code:
Here is the approach:
- Initialization:
- Initialize a deque with all elements of the array and set
currentWinner
to the first element. - Store the original value of
k
inoriginalK
and calculate the maximum elementmaxElement
in the array.
- Initialize a deque with all elements of the array and set
- Edge Case:
- If
k
is greater than or equal to the array size, the maximum element will naturally win. Therefore, returnmaxElement
.
- If
- Game Loop:
- Continue the game while the number of consecutive wins by
currentWinner
is less thank
. - In each iteration, dequeue the next element.
- Compare
currentWinner
with the next element:- If
currentWinner
is greater, increment theconsecutiveWins
counter and enqueue the next element to the end of the deque. - If the next element is greater, reset the
consecutiveWins
to 1, enqueuecurrentWinner
, and updatecurrentWinner
to the next element.
- If
- Continue the game while the number of consecutive wins by
- Return Result:
- Once an element wins
k
consecutive rounds, returncurrentWinner
as the winner.
- Once an element wins
Code
Java
public class Solution {
public int getWinner(int[] arr, int k) {
Deque<Integer> deque = new ArrayDeque<>();
for (int i : arr) {
deque.offer(i);
}
int currentWinner = deque.poll();
int originalK = k;
int maxElement = Arrays.stream(arr).max().getAsInt();
// If k is greater than or equal to the array size, the maximum element
// will naturally win
if (k >= arr.length) {
return maxElement;
}
int consecutiveWins = 0;
while (consecutiveWins < k) {
int next = deque.poll();
if (currentWinner > next) {
consecutiveWins++;
deque.offer(next);
} else {
consecutiveWins = 1;
deque.offer(currentWinner);
currentWinner = next;
}
}
return currentWinner;
}
}
Python
def get_winner(arr, k):
dq = deque(arr)
current_winner = dq.popleft()
original_k = k
max_element = max(arr)
# If k is greater than or equal to the array size, the maximum element will naturally win
if k >= len(arr):
return max_element
consecutive_wins = 0
while consecutive_wins < k:
next_element = dq.popleft()
if current_winner > next_element:
consecutive_wins += 1
dq.append(next_element)
else:
consecutive_wins = 1
dq.append(current_winner)
current_winner = next_element
return current_winner
Complexity
- Time:
O(n + m)
, wheren
is the length of the array andm
is the number of operations required to find the winner. In the worst case, it can beO(n * k)
. - Space:
O(n)
, due to the space required to store the elements in the deque.
Method 3 - Two Pointer and Hashtable
Here is the approach:
- Initialization:
- Initialize a dictionary
wins
to keep track of the number of wins for each integer. - Initialize two pointers
i
andj
to traverse the array starting from positions0
and1
, respectively.
- Initialize a dictionary
- Game Loop:
- Continue the loop as long as both
i
andj
are within the bounds of the array. - Compare
arr[i]
andarr[j]
:- If
arr[i]
is greater, increment the win count forarr[i]
in thewins
dictionary and move to the next element by incrementingj
. - If
arr[j]
is greater, increment the win count forarr[j]
, seti
toj
, and move to the next element by incrementingj
.
- If
- If the win count for
arr[i]
equalsk
, returnarr[i]
as the winner.
- Continue the loop as long as both
- Edge Case:
- If no integer wins
k
consecutive rounds within the loop, find and return the maximum integer in the array as the winner.
- If no integer wins
- Return the Winner:
- The element with
k
consecutive wins is returned as the winner. - If no such element is found within the loop, return the maximum element in the array.
- The element with
Code
Java
public class Solution {
public int getWinner(int[] arr, int k) {
int n = arr.length;
HashMap<Integer, Integer> wins = new HashMap<>();
int i = 0, j = 1;
while (i < n && j < n) {
if (arr[i] > arr[j]) {
wins.put(arr[i], wins.getOrDefault(arr[i], 0) + 1);
} else {
wins.put(arr[j], wins.getOrDefault(arr[j], 0) + 1);
i = j;
}
if (wins.get(arr[i]) == k) {
return arr[i];
}
j++;
}
return Arrays.stream(arr).max().getAsInt();
}
}
Python
def get_winner(arr, k):
from collections import defaultdict
n = len(arr)
wins = defaultdict(int)
i = 0
j = 1
while i < n and j < n:
if arr[i] > arr[j]:
wins[arr[i]] += 1
else:
wins[arr[j]] += 1
i = j
if wins[arr[i]] == k:
return arr[i]
j += 1
return max(arr)
Complexity
- ⏰ Time complexity:
O(n)
, wheren
is the length of the array, because each element is processed at most twice. - 🧺 Space complexity:
O(n)
, due to the dictionary used to store the number of wins for each integer.