3238. Find the Number of Winning Players
Problem Description
You have n
players in a game, numbered from 0
to n-1
. Each player picks colored balls during the game.
You're given a 2D array pick
where pick[i] = [xi, yi]
means player xi
picked a ball of color yi
.
The winning condition for each player is based on their player number:
- Player
0
wins if they pick any ball (at least 1 ball of any color) - Player
1
wins if they pick at least 2 balls of the same color - Player
2
wins if they pick at least 3 balls of the same color - In general, player
i
wins if they pick at leasti + 1
balls of the same color
A player needs to have strictly more than i
balls of the same color to win. This means they need at least i + 1
balls of one specific color (not total balls).
Your task is to count how many players win the game. Note that multiple players can win simultaneously.
For example, if player 2
picks 3 red balls and 1 blue ball, they win because they have 3 balls of the same color (red), which is more than their player number (2).
Return the total number of winning players.
Intuition
To determine which players win, we need to track how many balls of each color each player has picked. Since a player wins if they have more than i
balls of the same color (where i
is their player number), we need to check if any color count exceeds their player number.
The key insight is that we need a way to:
- Count balls by player and by color - this suggests using a 2D array where
cnt[player][color]
stores how many balls of that color the player has picked - Track which players have already won - since we only want to count each winning player once (even if they satisfy the winning condition with multiple colors)
As we process each pick operation [x, y]
(player x
picks color y
), we increment the count for that player-color combination. Immediately after incrementing, we check if this player now meets the winning condition: does cnt[x][y] > x
?
If yes, we add player x
to our set of winners. Using a set is crucial here because:
- A player might pick enough balls of multiple colors to win (e.g., player 2 might pick 3 red balls AND 3 blue balls)
- We only want to count each winning player once, not multiple times
The final answer is simply the size of the set, which gives us the unique count of winning players.
The solution efficiently processes each pick in a single pass, updating counts and checking winning conditions on the fly, making it both time and space efficient.
Solution Approach
We implement the solution using a counting approach with two main data structures:
-
2D Array for Counting: Create a 2D array
cnt
of sizen × 11
wherecnt[x][y]
tracks how many balls of colory
playerx
has picked. We use 11 columns because the problem constraints typically limit colors to values 0-10. -
Set for Winners: Use a set
s
to store the IDs of players who have won. This ensures each winning player is counted only once.
The algorithm works as follows:
cnt = [[0] * 11 for _ in range(n)] # Initialize count array
s = set() # Initialize winner set
For each pick operation [x, y]
in the input:
- Increment the count:
cnt[x][y] += 1
- Check if player
x
now wins: ifcnt[x][y] > x
- If they win, add them to the set:
s.add(x)
for x, y in pick: cnt[x][y] += 1 if cnt[x][y] > x: s.add(x)
The winning condition cnt[x][y] > x
directly implements the rule that player i
needs strictly more than i
balls of the same color (i.e., at least i + 1
balls).
Finally, return len(s)
which gives the total number of unique winning players.
The time complexity is O(m)
where m
is the length of the pick array, as we process each pick exactly once. The space complexity is O(n)
for the counting array and the set.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example with n = 4
players and the following picks:
pick = [[0, 1], [1, 2], [1, 2], [2, 3], [2, 3], [2, 3], [3, 4]]
Initial Setup:
- Create a 2D array
cnt
of size 4×11 (all zeros initially) - Create an empty set
s
for tracking winners
Processing each pick:
-
Pick [0, 1]: Player 0 picks color 1
cnt[0][1] = 1
- Check: Is
cnt[0][1] > 0
? Yes! (1 > 0) - Player 0 wins! Add to set:
s = {0}
-
Pick [1, 2]: Player 1 picks color 2
cnt[1][2] = 1
- Check: Is
cnt[1][2] > 1
? No (1 is not > 1) - No win yet
-
Pick [1, 2]: Player 1 picks color 2 again
cnt[1][2] = 2
- Check: Is
cnt[1][2] > 1
? Yes! (2 > 1) - Player 1 wins! Add to set:
s = {0, 1}
-
Pick [2, 3]: Player 2 picks color 3
cnt[2][3] = 1
- Check: Is
cnt[2][3] > 2
? No (1 is not > 2) - No win yet
-
Pick [2, 3]: Player 2 picks color 3 again
cnt[2][3] = 2
- Check: Is
cnt[2][3] > 2
? No (2 is not > 2) - Still no win
-
Pick [2, 3]: Player 2 picks color 3 again
cnt[2][3] = 3
- Check: Is
cnt[2][3] > 2
? Yes! (3 > 2) - Player 2 wins! Add to set:
s = {0, 1, 2}
-
Pick [3, 4]: Player 3 picks color 4
cnt[3][4] = 1
- Check: Is
cnt[3][4] > 3
? No (1 is not > 3) - No win
Final Result:
- Set of winners:
s = {0, 1, 2}
- Return
len(s) = 3
Three players won the game:
- Player 0 needed > 0 balls of any color (got 1 ball of color 1) ✓
- Player 1 needed > 1 balls of same color (got 2 balls of color 2) ✓
- Player 2 needed > 2 balls of same color (got 3 balls of color 3) ✓
- Player 3 needed > 3 balls of same color (only got 1 ball) ✗
Solution Implementation
1class Solution:
2 def winningPlayerCount(self, n: int, pick: List[List[int]]) -> int:
3 # Create a 2D array to count balls of each color (0-10) for each player (0 to n-1)
4 # player_ball_count[player_id][color] = count of balls of that color for that player
5 player_ball_count = [[0] * 11 for _ in range(n)]
6
7 # Set to store unique player IDs who have won
8 winning_players = set()
9
10 # Process each pick
11 for player_id, ball_color in pick:
12 # Increment the count of balls of this color for this player
13 player_ball_count[player_id][ball_color] += 1
14
15 # Check if player has won: player i wins if they have more than i balls of any single color
16 if player_ball_count[player_id][ball_color] > player_id:
17 winning_players.add(player_id)
18
19 # Return the total number of winning players
20 return len(winning_players)
21
1class Solution {
2 public int winningPlayerCount(int n, int[][] pick) {
3 // Create a 2D array to count balls of each color (0-10) for each player
4 // playerBallCount[playerIndex][colorIndex] = count of balls of that color for that player
5 int[][] playerBallCount = new int[n][11];
6
7 // Set to store unique player indices who have won
8 Set<Integer> winningPlayers = new HashSet<>();
9
10 // Process each pick from the input
11 for (int[] currentPick : pick) {
12 int playerId = currentPick[0];
13 int ballColor = currentPick[1];
14
15 // Increment the count of balls of this color for this player
16 playerBallCount[playerId][ballColor]++;
17
18 // Check if player has won: player i wins if they have more than i balls of any single color
19 if (playerBallCount[playerId][ballColor] > playerId) {
20 winningPlayers.add(playerId);
21 }
22 }
23
24 // Return the total number of winning players
25 return winningPlayers.size();
26 }
27}
28
1class Solution {
2public:
3 int winningPlayerCount(int n, vector<vector<int>>& pick) {
4 // Create a 2D array to count balls picked by each player
5 // playerBallCount[playerId][color] = number of balls of 'color' picked by 'playerId'
6 // Max 10 players (0-9) and 11 colors (0-10)
7 int playerBallCount[10][11] = {};
8
9 // Set to store unique winning players
10 unordered_set<int> winningPlayers;
11
12 // Process each pick
13 for (const auto& currentPick : pick) {
14 int playerId = currentPick[0];
15 int ballColor = currentPick[1];
16
17 // Increment the count for this player and color
18 playerBallCount[playerId][ballColor]++;
19
20 // Check if player has won (picked more than their player number)
21 if (playerBallCount[playerId][ballColor] > playerId) {
22 winningPlayers.insert(playerId);
23 }
24 }
25
26 // Return the total number of winning players
27 return winningPlayers.size();
28 }
29};
30
1/**
2 * Counts the number of winning players based on pick conditions
3 * A player wins if they pick a specific number more times than their player ID
4 *
5 * @param n - Total number of players (0 to n-1)
6 * @param pick - Array of [playerId, pickedNumber] pairs
7 * @returns Number of winning players
8 */
9function winningPlayerCount(n: number, pick: number[][]): number {
10 // Initialize a 2D array to track count of each number (0-10) picked by each player
11 // playerPickCounts[playerId][number] = count of times player picked that number
12 const playerPickCounts: number[][] = Array.from(
13 { length: n },
14 () => Array(11).fill(0)
15 );
16
17 // Set to store unique winning player IDs
18 const winningPlayers = new Set<number>();
19
20 // Process each pick
21 for (const [playerId, pickedNumber] of pick) {
22 // Increment the count for this player picking this number
23 playerPickCounts[playerId][pickedNumber]++;
24
25 // Check if player has won: picked count > player ID
26 if (playerPickCounts[playerId][pickedNumber] > playerId) {
27 winningPlayers.add(playerId);
28 }
29 }
30
31 // Return the total number of winning players
32 return winningPlayers.size;
33}
34
Time and Space Complexity
The time complexity is O(m + n × M)
, where:
m
is the length of thepick
array (number of picks)n
is the number of playersM
is the number of colors (which is 11 in this implementation)
Breaking down the time complexity:
- Initializing the 2D array
cnt
takesO(n × M)
time, as we createn
lists each containingM
elements - Iterating through the
pick
array takesO(m)
time, with each operation inside the loop (array access, increment, comparison, and set addition) takingO(1)
time - Therefore, the total time complexity is
O(n × M + m)
, which can be written asO(m + n × M)
The space complexity is O(n × M)
, where:
- The 2D array
cnt
usesO(n × M)
space to store the count of each color for each player - The set
s
uses at mostO(n)
space to store winning players, which is bounded byO(n × M)
- Therefore, the dominant space complexity is
O(n × M)
Since M = 11
is a constant in this implementation, the complexities can also be expressed as O(m + n)
for time and O(n)
for space in practical terms.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Misunderstanding the Winning Condition
The most common mistake is misinterpreting the winning rule. Players need strictly more than their player number of balls of the same color, not total balls across all colors.
Incorrect interpretation:
# WRONG: Counting total balls for a player
total_balls = sum(player_ball_count[player_id])
if total_balls > player_id:
winning_players.add(player_id)
Correct interpretation:
# RIGHT: Check if any single color has more than player_id balls if player_ball_count[player_id][ball_color] > player_id: winning_players.add(player_id)
2. Using Wrong Comparison Operator
Another frequent error is using >=
instead of >
for the winning condition. Player i
needs strictly more than i
balls (which means at least i + 1
balls).
Incorrect:
# WRONG: This would mean player 0 wins with 0 balls if player_ball_count[player_id][ball_color] >= player_id: winning_players.add(player_id)
Correct:
# RIGHT: Player i needs at least i + 1 balls if player_ball_count[player_id][ball_color] > player_id: winning_players.add(player_id)
3. Hardcoding Color Range
The solution assumes colors are in range 0-10 by creating an array with 11 columns. If the problem doesn't specify this constraint or if colors can be any integer, this approach fails.
Better approach using dictionary:
from collections import defaultdict
player_ball_count = defaultdict(lambda: defaultdict(int))
winning_players = set()
for player_id, ball_color in pick:
player_ball_count[player_id][ball_color] += 1
if player_ball_count[player_id][ball_color] > player_id:
winning_players.add(player_id)
4. Not Using a Set for Winners
Using a list instead of a set to track winners can lead to counting the same player multiple times if they satisfy the winning condition with different colors.
Incorrect:
# WRONG: Could count the same player multiple times
winners = []
for player_id, ball_color in pick:
player_ball_count[player_id][ball_color] += 1
if player_ball_count[player_id][ball_color] > player_id:
winners.append(player_id) # Duplicate entries possible
return len(winners)
Correct:
# RIGHT: Set ensures each player is counted only once
winning_players = set()
# ... processing picks ...
winning_players.add(player_id) # Automatically handles duplicates
Which two pointer techniques do you use to check if a string is a palindrome?
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!