leetcode
leetcode 2501 ~ 2550
找到冠军 II

找到冠军 II

难度:

标签:

题目描述

There are n teams numbered from 0 to n - 1 in a tournament; each team is also a node in a DAG.

You are given the integer n and a 0-indexed 2D integer array edges of length m representing the DAG, where edges[i] = [ui, vi] indicates that there is a directed edge from team ui to team vi in the graph.

A directed edge from a to b in the graph means that team a is stronger than team b and team b is weaker than team a.

Team a will be the champion of the tournament if there is no team b that is stronger than team a.

Return the team that will be the champion of the tournament if there is a unique champion, otherwise, return -1.

Notes

  • A cycle is a series of nodes a1, a2, ..., an, an+1 such that node a1 is the same node as node an+1, the nodes a1, a2, ..., an are distinct, and there is a directed edge from the node ai to node ai+1 for every i in the range [1, n].
  • A DAG is a directed graph that does not have any cycle.

 

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.

代码结果

运行时间: 51 ms, 内存: 17.0 MB


/*
题目思路:
使用Java Stream API来实现相同的逻辑,我们可以首先计算每个节点的入度,然后过滤出入度为0的节点。
如果有且只有一个入度为0的节点,那么它就是冠军队伍,否则返回-1。
*/

import java.util.*;
import java.util.stream.*;

public class ChampionTeamStream {
    public int findChampion(int n, int[][] edges) {
        int[] inDegree = new int[n];
        Arrays.stream(edges).forEach(edge -> inDegree[edge[1]]++);
        List<Integer> potentialChampions = IntStream.range(0, n)
                                                    .filter(i -> inDegree[i] == 0)
                                                    .boxed()
                                                    .collect(Collectors.toList());
        return potentialChampions.size() == 1 ? potentialChampions.get(0) : -1;
    }
}

解释

方法:

题解通过维护一个包含所有队伍的列表来标记可能的冠军队伍。遍历给定的边,对于每一条边 [u, v],标记 v 队因为存在比它强的 u 队而不可能是冠军,通过将 champion[v] 设为 -1 实现。最后,所有未被标记为 -1 的队伍即是没有比它强的队伍的候选者。如果存在唯一的候选者,则这个候选者是冠军;如果不存在或存在多个,则返回 -1。

时间复杂度:

O(n + m)

空间复杂度:

O(n)

代码细节讲解

🦆
题解中的算法是否考虑了图中潜在的孤立节点,即那些既没有入边也没有出边的节点?
题解中的算法没有直接考虑孤立节点的情况。因为算法是通过遍历边来标记非冠军队伍的,所以任何未在边中出现的节点都不会被标记为-1。如果一个节点即没有入边也没有出边,它将不会被任何边的遍历影响,从而保留在可能的冠军列表中。这意味着孤立节点仍然被视为可能的冠军候选,除非存在其他未被标记的节点。
🦆
在遍历edges数组时,程序中对champion数组的更新是否可能对后续判断产生先后顺序的影响,比如对于不同顺序的边输入结果是否一致?
题解中对champion数组的更新方式保证了边的输入顺序不会影响最终的结果。由于每个边的遍历都是将目标节点(即边的第二个元素)标记为-1,这个操作是幂等的,即多次对同一节点进行此操作与进行一次操作的结果相同。因此,不论边的输入顺序如何,最后被标记为-1的节点集合都将是相同的,从而保证了结果的一致性。
🦆
如果图中所有的边都是从一个节点指向同一个节点,题解的方法是否还能有效地找出冠军?
如果所有的边都是从一个或多个节点指向同一个节点,那么这个目标节点将被标记为-1,因为它有入边表示存在比它强的队伍。其他所有未被标记的节点都没有入边,这意味着没有其他节点比它们强,因此这些未被标记的节点都是冠军的候选。如果除了被指向的节点外只有一个未被标记的节点,则该节点是冠军。如果有多个这样的节点,解决方案无法确定唯一的冠军,将返回-1。
🦆
题解算法中返回-1的条件是没有冠军或存在多个冠军,那么如何区分这两种情况,是否需要额外的逻辑来明确区分?
当前题解的算法设计中并没有区分'没有冠军'与'存在多个冠军'的情况。在实际应用中,如果需要明确区分这两种情况,可以引入额外的逻辑。例如,可以计算结果列表ans的长度,如果长度为0,则没有冠军;如果长度大于1,则存在多个冠军。这样可以通过长度来明确返回的-1是由于哪种情况引起的,从而提供更详细的信息。

相关问题