Facebook Pixel

3238. Find the Number of Winning Players

EasyArrayHash TableCounting
Leetcode Link

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 least i + 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.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

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:

  1. 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
  2. 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:

  1. 2D Array for Counting: Create a 2D array cnt of size n × 11 where cnt[x][y] tracks how many balls of color y player x has picked. We use 11 columns because the problem constraints typically limit colors to values 0-10.

  2. 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: if cnt[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 Evaluator

Example 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:

  1. 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}
  2. 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
  3. 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}
  4. 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
  5. 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
  6. 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}
  7. 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 the pick array (number of picks)
  • n is the number of players
  • M is the number of colors (which is 11 in this implementation)

Breaking down the time complexity:

  • Initializing the 2D array cnt takes O(n × M) time, as we create n lists each containing M elements
  • Iterating through the pick array takes O(m) time, with each operation inside the loop (array access, increment, comparison, and set addition) taking O(1) time
  • Therefore, the total time complexity is O(n × M + m), which can be written as O(m + n × M)

The space complexity is O(n × M), where:

  • The 2D array cnt uses O(n × M) space to store the count of each color for each player
  • The set s uses at most O(n) space to store winning players, which is bounded by O(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
Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

Which two pointer techniques do you use to check if a string is a palindrome?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More