LC每日一题|20240412 - 2923. 找到冠军 I

105 阅读4分钟

LC每日一题|20240412 - 2923. 找到冠军 I

一场比赛中共有 n 支队伍,按从 0 到  n - 1 编号。

给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 <= i, j <= n - 1i != j 的所有 i, j :如果 grid[i][j] == 1,那么 i 队比 j ;否则,j 队比 i

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

返回这场比赛中将会成为冠军的队伍。

提示:

  • n == grid.length
  • n == grid[i].length
  • 2 <= n <= 100
  • grid[i][j] 的值为 01
  • 对于所有 i grid[i][i] 等于 0.
  • 对于满足 i != j 的所有 i, jgrid[i][j] != grid[j][i] 均成立
  • 生成的输入满足:如果 a 队比 b 队强,b 队比 c 队强,那么 a 队比 c 队强

题目级别:Easy

解题思路

确实是一道很easy的Easy题。

只需要判断 grid[i]1 的数量即可。因为冠军队比除它自己以外的所有队都强,故其 1 的数量应该是 队伍数量 - 1

AC代码

class Solution {
    fun findChampion(grid: Array<IntArray>): Int {
        for (i in grid.indices) if (grid[i].sum() == grid.size - 1) return i
        return -1
    }
}

时间复杂度:O(n^2)

空间复杂度:O(1)

优化方案

受到 PH佬 @Paperhammer 在B站发的 视频 的启发,我发现上述算法其实是有优化空间的,其时间复杂度可以被优化到 O(n)

我自己平时刷题的时候确实疏于对 复杂度优化一题多解 的重视,这可能就是我作为追赶者与各位先进的差距之一。

class Solution {
    fun findChampion(grid: Array<IntArray>): Int {
        var res = 0
        for (i in grid.indices) if (grid[i][res] == 1) res = i
        return res
    }
}

进阶⬆️

这一题还有一个进阶 - 2924. 找到冠军 II,也是非常简单的。

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

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

a 队到 b 队的有向边意味着 a 队比 b ,也就是 b 队比 a

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

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

注意

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

提示:

  • 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]
  • 生成的输入满足:如果 a 队比 b 队强,就不存在 b 队比 a 队强
  • 生成的输入满足:如果 a 队比 b 队强,b 队比 c 队强,那么 a 队比 c 队强

题目级别:Medium

解题思路

这题虽然已经是上一道题的进阶了,但其难度在 Easy 中仍然属于 中等偏简单 的水平,这个 Medium 名不副实

我们只需要统计所有节点的 入度 ,获取入度为 0 的节点即可。根据题意,如果有超过 1 个节点的入度为 0 ,则返回 -1

AC代码

class Solution {
    fun findChampion(n: Int, edges: Array<IntArray>): Int {
        val map = IntArray(n) 
        edges.forEach { map[it[1]]++ }
        val first = map.indexOf(0)
        val last = map.lastIndexOf(0)
        return if (first == last) first else -1
    }
}

碎碎念

这是某一场LC周赛的 T1T2

这两道题,尤其 T2完全不是LC周赛T2的正常难度水平

合理推测,如果参赛者不能在10分钟内AC这两道题,那么其实时rank应该不会低于1500...