Find Champion II

Updated on 28 May, 2025
Find Champion II header image

Problem Statement

In a tournament with n teams where each team is also represented as a node in a Directed Acyclic Graph (DAG), we are provided with the number of teams n and a list of directed edges between these teams. These edges represent a directional "stronger-than" relationship between teams. Specifically, a directed edge [ui, vi] from team ui to team vi indicates that team ui is stronger than team vi. The goal is to determine the "champion" of the tournament. The champion is defined as a team that has no other team stronger than it. We have to return the identifier of this champion team if it is unique; if there is no unique champion or the strongest hierarchy is not maintained as per the rules, we should return -1.

This situation is modeled in a graph where each node represents a team and each directed edge denotes a stronger relation. We need to check for the presence of a unique top node (with no incoming stronger edges) in this graph structure.

Examples

Example 1

Input:

n = 3, edges = [[0,1],[1,2]]

Output:

0

Explanation: Team 1 is weaker than team 0. Team 2 is weaker than team 1. So the champion is team 0.

Example 2

Input:

n = 4, edges = [[0,2],[1,3],[1,2]]

Output:

-1

Explanation:

Team 2 is weaker than team 0 and team 1. Team 3 is weaker than team 1. But team 1 and team 0 are not weaker than any other teams. So the answer is -1.

Constraints

  • 1 <= n <= 100
  • m == edges.length
  • 0 <= m <= n * (n - 1) / 2
  • edges[i].length == 2
  • 0 <= edge[i][j] <= n - 1
  • edges[i][0] != edges[i][1]
  • The input is generated such that if team a is stronger than team b, team b is not stronger than team a.
  • The input is generated such that if team a is stronger than team b and team b is stronger than team c, then team a is stronger than team c.

Approach and Intuition

Given the graph-based nature of this problem, represented by nodes (teams) and directed edges (stronger relations), we focus on identifying the node with zero incoming edges.

  1. If a team serves as the champion, it implies that all directed edges only point away from this team, meaning this node in the DAG has zero incoming edges but could potentially have outgoing edges to several other nodes.
  2. To find such a node, we can:
    • Initialize an array, indegree, of size n with all zeros to keep a count of incoming edges for each team.
    • Process each edge in the edges list to populate this indegree array. For each directed edge [u, v], it means there is an incoming edge to team v from team u, so we increment indegree[v] by one.
    • After processing all edges, the champion team should then be the only team that has an indegree of zero.
  3. Extra checks:
    • Ensure exactly one team has indegree zero to qualify as a unique champion. If no teams or more than one team have indegree zero, return -1.
    • The constraints and the nature of the problem (dealing with a DAG and the defined strength relationships) ensure that there are no cycles and that the strength relationships are transitive, which simplifies our approach and ensures it’ll run efficiently due to the bounded size of n.

By following these steps, one can determine the unique champion of the tournament or establish that no unique champion exists, directly from the relation dynamics described by the given edges in this DAG.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int determineWinner(int n, vector<vector<int>>& links) {
        vector<int> incomingEdges(n, 0);
        for (auto link : links) {
            incomingEdges[link[1]]++;
        }

        int winner = -1, potentialWinners = 0;
        for (int i = 0; i < n; i++) {
            if (incomingEdges[i] == 0) {
                potentialWinners++;
                winner = i;
            }
        }

        return potentialWinners > 1 ? -1 : winner;
    }
};

This C++ program provides a solution to find a "champion" or winner from a list of competitors based on a directed graph approach where each competitor is represented as a node and each competitive relationship as a directed edge. Here's a breakdown of how the solution handles the problem:

  • The function determineWinner accepts two parameters: an integer n representing the total number of competitors and a 2D vector links where each sub-vector contains two integers representing a directed edge from the first competitor to the second, indicating that the second competitor has beaten the first.
  • An integer vector incomingEdges keeps a count of incoming edges (beat paths) for each competitor. This is initialized to zero for all competitors.
  • The function iterates over each link (competitive relationship) and increments the count of incoming edges for competitors who have been defeated as depicted by the links.
  • After establishing the number of defeats each competitor has, the code iterates through the incomingEdges vector to determine competitors with no defeats (incomingEdges[i] == 0).
  • The code identifies if there is exactly one competitor with zero defeats. If not, it returns -1, indicating no clear champion or multiple potential champions. If there is exactly one, it returns the index of that competitor, marking them as the winner.

In essence, the solution checks for a node (competitor) in a directed graph that has no incoming edges, which means no other node is directed towards it, implying no defeats. If there's only one such node, it's the champion; otherwise, there's a conflict in determining a unique winner.

java
public class Solution {

    public int findWinner(int teamCount, int[][] relationships) {
        // Track number of incoming edges for each team
        int[] incomingEdges = new int[teamCount];

        // Increment incoming edges count for each team
        for (int[] relation : relationships) {
            incomingEdges[relation[1]]++;
        }

        int winner = -1;
        int singleWinnerCount = 0;

        // Check each team for zero incoming edges
        for (int team = 0; team < teamCount; team++) {
            if (incomingEdges[team] == 0) {
                singleWinnerCount++;
                winner = team;
            }
        }

        // Determine if there is a unique winner
        return singleWinnerCount > 1 ? -1 : winner;
    }
}

The provided Java solution detects the winner in a scenario where multiple teams are compared based on their relationships. The function findWinner accepts the total number of teams and a list of relationships between them, determining who could potentially be the champion.

Here's how the solution operates:

  • An array incomingEdges is initialized to track the number of incoming relationships (defeats) each team has from other teams in the form of directed edges.
  • As each relationship is processed, the method increments the count of incoming edges for the team that was defeated.
  • After processing all relationships, the program searches for the team with zero incoming edges, which indicates no defeats, naming it as the potential winner.
  • If exactly one team is found with zero incoming edges, it is declared the winner. If more than one such team exists, indicating no clear winner, the function returns -1.

Ensure that the input (number of teams and relationships) is correctly formatted to avoid errors during the array operations. This solution efficiently handles delineating the potential winner in a simple and understandable manner.

python
class Solution:
    def determineChampion(self, total_teams: int, relations: list[list[int]]) -> int:
        team_incoming_edges = [0] * total_teams
        for relation in relations:
            team_incoming_edges[relation[1]] += 1

        potential_champion = -1
        champions_found = 0

        for team_id in range(total_teams):
            if team_incoming_edges[team_id] == 0:
                champions_found += 1
                potential_champion = team_id
        
        return potential_champion if champions_found == 1 else -1

Solution summary for finding a champion from a number of teams based on their relationships, implemented in Python:

  • The code defines a class Solution with the method determineChampion, which takes total_teams (an integer that represents the number of teams) and relations (a list of lists, where each sub-list has two integers representing a directional relationship from one team to another).
  • Begin by initializing an array team_incoming_edges with zeros, sized by total_teams. This array tracks the number of direct losses each team has; a loss is indicated by another team pointing to a team in the relations.
  • Loop through each relation, incrementing the incoming edge count for teams that have been defeated as indicated by the second element in each sub-list in relations.
  • Establish default values for potential_champion as -1 and champions_found as 0.
  • Iterate through teams by their indices. If a team has no incoming losses (team_incoming_edges[team_id] == 0), it's a candidate for champion, increment champions_found and update potential_champion with the current team_id.
  • If exactly one champion candidate is found (champions_found == 1), return the potential_champion. Otherwise, return -1 indicating no unique champion is determined.

This code effectively identifies if there is a unique team that does not have any defeats. If multiple undefeated teams exist or all teams have been defeated, it returns -1 to indicate the absence of a unique champion.

Comments

No comments yet.