class Solution:
def findWinners(self, matches):
from collections import defaultdict
loss_count = defaultdict(int)
players = set()
for winner, loser in matches:
players.add(winner)
players.add(loser)
loss_count[loser] += 1
zero_losses = []
one_loss = []
for player in players:
if loss_count[player] == 0:
zero_losses.append(player)
elif loss_count[player] == 1:
one_loss.append(player)
return [sorted(zero_losses), sorted(one_loss)]
class Solution {
public:
vector<vector<int>> findWinners(vector<vector<int>>& matches) {
unordered_map<int, int> loss_count;
unordered_set<int> players;
for (auto& match : matches) {
int winner = match[0], loser = match[1];
players.insert(winner);
players.insert(loser);
loss_count[loser]++;
}
vector<int> zero_losses, one_loss;
for (int player : players) {
if (loss_count[player] == 0)
zero_losses.push_back(player);
else if (loss_count[player] == 1)
one_loss.push_back(player);
}
sort(zero_losses.begin(), zero_losses.end());
sort(one_loss.begin(), one_loss.end());
return {zero_losses, one_loss};
}
};
import java.util.*;
class Solution {
public List<List<Integer>> findWinners(int[][] matches) {
Map<Integer, Integer> lossCount = new HashMap<>();
Set<Integer> players = new HashSet<>();
for (int[] match : matches) {
int winner = match[0], loser = match[1];
players.add(winner);
players.add(loser);
lossCount.put(loser, lossCount.getOrDefault(loser, 0) + 1);
}
List<Integer> zeroLosses = new ArrayList<>();
List<Integer> oneLoss = new ArrayList<>();
for (int player : players) {
int losses = lossCount.getOrDefault(player, 0);
if (losses == 0) {
zeroLosses.add(player);
} else if (losses == 1) {
oneLoss.add(player);
}
}
Collections.sort(zeroLosses);
Collections.sort(oneLoss);
List<List<Integer>> result = new ArrayList<>();
result.add(zeroLosses);
result.add(oneLoss);
return result;
}
}
var findWinners = function(matches) {
const lossCount = new Map();
const players = new Set();
for (const [winner, loser] of matches) {
players.add(winner);
players.add(loser);
lossCount.set(loser, (lossCount.get(loser) || 0) + 1);
}
const zeroLosses = [];
const oneLoss = [];
for (const player of players) {
const losses = lossCount.get(player) || 0;
if (losses === 0) zeroLosses.push(player);
else if (losses === 1) oneLoss.push(player);
}
zeroLosses.sort((a, b) => a - b);
oneLoss.sort((a, b) => a - b);
return [zeroLosses, oneLoss];
};
Given a list called matches
, where each element is a pair [winner, loser]
representing the result of a match between two players, your task is to find:
Return a list containing two lists:
To solve this problem, we need to efficiently track how many times each player has lost. The naive approach would be to check every player against every match, but that would be slow and repetitive. Instead, we can use a data structure to count losses for each player as we process the matches.
The key insight is that the number of losses for each player is all we care about. Once we know each player's loss count, we can easily group them into the two required categories. This suggests using a hash map (dictionary) to map each player to their loss count, which allows us to update and access counts quickly.
We also need to make sure we include players who have never lost, even if they only appear as winners. So, we need to collect the set of all players seen in any match.
[winner, loser]
in matches
:winner
and loser
to the set of players.loser
by 1 in the hash map.This approach is efficient because:
Let's walk through an example:
matches = [[1,2],[2,3],[4,2],[1,5]]
[[1, 4], [3, 5]]
The solution efficiently tracks each player's loss count using a hash map while collecting all players in a set. After processing all matches, we simply categorize players by their loss counts and sort the results. This approach is both simple and efficient, making good use of hash maps for constant-time updates and lookups. The main insight is that only the loss count per player matters, allowing us to avoid unnecessary repeated scanning of the matches.