Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1212. Team Scores in Football Tournament - Leetcode Solution

Code Implementation

from collections import defaultdict

def teamScores(matches):
    scores = defaultdict(int)
    for match in matches:
        team1, team2, score1, score2 = match
        if score1 > score2:
            scores[team1] += 3
            scores[team2] += 0
        elif score1 < score2:
            scores[team1] += 0
            scores[team2] += 3
        else:
            scores[team1] += 1
            scores[team2] += 1
    return dict(scores)
      
#include <unordered_map>
#include <string>
#include <vector>
using namespace std;

unordered_map<string, int> teamScores(const vector<vector<string>>& matches) {
    unordered_map<string, int> scores;
    for (const auto& match : matches) {
        string team1 = match[0], team2 = match[1];
        int score1 = stoi(match[2]), score2 = stoi(match[3]);
        if (score1 > score2) {
            scores[team1] += 3;
            scores[team2] += 0;
        } else if (score1 < score2) {
            scores[team1] += 0;
            scores[team2] += 3;
        } else {
            scores[team1] += 1;
            scores[team2] += 1;
        }
    }
    return scores;
}
      
import java.util.*;

public class Solution {
    public Map<String, Integer> teamScores(List<List<String>> matches) {
        Map<String, Integer> scores = new HashMap<>();
        for (List<String> match : matches) {
            String team1 = match.get(0), team2 = match.get(1);
            int score1 = Integer.parseInt(match.get(2)), score2 = Integer.parseInt(match.get(3));
            scores.putIfAbsent(team1, 0);
            scores.putIfAbsent(team2, 0);
            if (score1 > score2) {
                scores.put(team1, scores.get(team1) + 3);
            } else if (score1 < score2) {
                scores.put(team2, scores.get(team2) + 3);
            } else {
                scores.put(team1, scores.get(team1) + 1);
                scores.put(team2, scores.get(team2) + 1);
            }
        }
        return scores;
    }
}
      
function teamScores(matches) {
    const scores = {};
    for (const match of matches) {
        const [team1, team2, score1, score2] = match;
        if (!(team1 in scores)) scores[team1] = 0;
        if (!(team2 in scores)) scores[team2] = 0;
        if (score1 > score2) {
            scores[team1] += 3;
        } else if (score1 < score2) {
            scores[team2] += 3;
        } else {
            scores[team1] += 1;
            scores[team2] += 1;
        }
    }
    return scores;
}
      

Problem Description

In the "Team Scores in Football Tournament" problem, you are given a list called matches. Each element in matches represents a match and is formatted as [team1, team2, score1, score2], where:
  • team1 and team2 are strings representing the names of the two teams that played.
  • score1 and score2 are integers representing the number of goals scored by team1 and team2 respectively.
The task is to compute the total tournament points for each team. Points are awarded as follows:
  • 3 points for a win
  • 1 point for a draw
  • 0 points for a loss
You should return a mapping (such as a dictionary or hash map) from team name to its total points after all matches have been played.

Thought Process

To solve this problem, start by considering how you would manually tally up scores for each team:
  • For each match, look at the scores to decide which team won, lost, or if it was a draw.
  • Add the appropriate points to each team's total.
  • Repeat this for every match, keeping a running total for every team.
The brute-force way would be to loop through each match and, for each team, keep updating their score in some data structure. Since teams can appear in any order and may not be known ahead of time, we need a way to dynamically store and update each team's score as we process the matches. A hash map (dictionary) is ideal for this because it provides fast lookups and updates.

Solution Approach

The solution uses a hash map (dictionary) to keep track of each team's points. Here's how we do it step by step:
  1. Initialize a hash map: Create an empty mapping from team names to their cumulative points.
  2. Process each match: For each match in matches:
    • Extract the team names and scores.
    • If a team is not already in the map, add it with a starting score of 0.
    • Compare the scores:
      • If score1 > score2, award 3 points to team1.
      • If score1 < score2, award 3 points to team2.
      • If score1 == score2, award 1 point to each team.
  3. Return the results: After all matches are processed, return the hash map containing each team's total points.

This approach is efficient because each match is processed exactly once and updating the hash map is a constant-time operation.

Example Walkthrough

Let's consider the following input:
  matches = [
    ["A", "B", 2, 1],
    ["A", "C", 1, 1],
    ["B", "C", 0, 3]
  ]
  
Step-by-step:
  • First match: "A" vs "B", 2-1. "A" wins, gets 3 points. "B" gets 0.
  • Second match: "A" vs "C", 1-1. Draw, both "A" and "C" get 1 point.
  • Third match: "B" vs "C", 0-3. "C" wins, gets 3 points. "B" gets 0.
Tallying up:
  • "A": 3 (win) + 1 (draw) = 4 points
  • "B": 0 (loss) + 0 (loss) = 0 points
  • "C": 1 (draw) + 3 (win) = 4 points
Final output should be: {"A": 4, "B": 0, "C": 4}

Time and Space Complexity

  • Brute-force approach: If you tried to tally points by scanning through all matches for each team, it would be O(n * t), where n is the number of matches and t is the number of teams. This is inefficient.
  • Optimized approach (hash map): We process each match once (O(n)), and each hash map update is O(1). So the total time complexity is O(n).
  • Space complexity: We store a score for each team, so space is O(t), where t is the number of unique teams.
This makes the hash map solution both time- and space-efficient.

Summary

The key to solving the "Team Scores in Football Tournament" problem is to use a hash map to dynamically tally each team's points as you process each match. This approach is elegant because it leverages fast lookups and updates, requires only a single pass through the data, and naturally accommodates an unknown number of teams. By focusing on efficient data structures and step-by-step processing, we achieve a concise and performant solution.