原题链接

题目描述

一场比赛中共有 nn 支队伍,按从 00n1n - 1 编号。每支队伍也是 有向无环图(DAG) 上的一个节点。

给你一个整数 nn 和一个下标从 00 开始、长度为 mm 的二维整数数组 edges 表示这个有向无环图,其中 edges[i] = [ui, vi] 表示图中存在一条从 uiu_i 队到 viv_i 队的有向边。

aa 队到 bb 队的有向边意味着 aa 队比 bb ,也就是 bb 队比 aa

在这场比赛中,如果不存在某支强于 aa 队的队伍,则认为 aa 队将会是 冠军

如果这场比赛存在 唯一 一个冠军,则返回将会成为冠军的队伍。否则,返回 1-1

注意

  • 是形如 a1,a2,...,an,an+1a_1, a_2, ..., a_n, a_{n+1} 的一个序列,且满足:节点 a1a_1 与节点an+1a_{n+1} 是同一个节点;节点 a1,a2,...,ana_1, a_2, ..., a_n 互不相同;对于范围[1,n][1, n] 中的每个 ii ,均存在一条从节点 aia_i 到节点 ai+1a_{i+1} 的有向边。
  • 有向无环图 是不存在任何环的有向图。

示例 1:

img

输入:n = 3, edges = [[0,1],[1,2]]
输出:0
解释:1 队比 0 队弱。2 队比 1 队弱。所以冠军是 0 队。

示例 2:

img

输入:n = 4, edges = [[0,2],[1,3],[1,2]]
输出:-1
解释:2 队比 0 队和 1 队弱。3 队比 1 队弱。但是 1 队和 0 队之间不存在强弱对比。所以答案是 -1

提示:

  • 1n1001 \le n \le 100
  • m==edges.lengthm == edges.length
  • 0mn(n1)20 \le m \le \frac { n * (n - 1) } 2
  • edges[i].length==2edges[i].length == 2
  • 0edge[i][j]n10 \le edge[i][j] \le n - 1
  • edges[i][0]!=edges[i][1]edges[i][0] != edges[i][1]
  • 生成的输入满足:如果 a 队比 b 队强,就不存在 b 队比 a 队强
  • 生成的输入满足:如果 a 队比 b 队强,b 队比 c 队强,那么 a 队比 c 队强

直接遍历

由题可知,如果是冠军的话,是没有入边的,即i!=edges[j][1]i != edges[j][1]。所以,可以很轻易写出时间复杂度为O(nm)O(n * m),空间复杂度为:O(n)O(n)的算法。

注意:可能存在多个没有入边的点,所以要数一下。

class Solution {
public:
    int findChampion(int n, vector<vector<int>>& edges) {
        int res = -1, cnt = 0;
        for ( int i = 0; i < n; i ++ ) {
            bool f = true;
            for ( int j = 0; j < edges.size(); j ++ )
                if ( edges[j][1] == i ) {
                    f = false;
                    break;
                }
            if ( f ) {
                res = i;
                cnt ++;
            }
        }
        return cnt == 1 ? res : -1;
    }
};

上面代码可以优化成时间复杂度为O(n+m)O(n + m),空间复杂度为O(n)O(n)的算法。

只需要开一个数据来记录第 ii 只队伍是否有入边即可。

class Solution {
public:
    int findChampion(int n, vector<vector<int>>& edges) {
        vector<bool> degree(n, false);
        for ( const auto &e : edges )
            degree[e[1]] = true;

        int res = -1, cnt = 0;

        for ( int i = 0; i < n; i ++ ) {
            if ( !degree[i] ) {
                cnt ++;
                res = i;
            }
        }
        return cnt == 1 ? res : -1;
    }
};