LC每日一题|20240412 - 2923. 找到冠军 I
一场比赛中共有
n支队伍,按从0到n - 1编号。给你一个下标从 0 开始、大小为
n * n的二维布尔矩阵grid。对于满足0 <= i, j <= n - 1且i != j的所有i, j:如果grid[i][j] == 1,那么i队比j队 强 ;否则,j队比i队 强 。在这场比赛中,如果不存在某支强于
a队的队伍,则认为a队将会是 冠军 。返回这场比赛中将会成为冠军的队伍。
提示:
n == grid.lengthn == grid[i].length2 <= n <= 100grid[i][j]的值为0或1- 对于所有
i,grid[i][i]等于0. - 对于满足
i != j的所有i, j,grid[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 <= 100m == edges.length0 <= m <= n * (n - 1) / 2edges[i].length == 20 <= edge[i][j] <= n - 1edges[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周赛的 T1 和 T2。
这两道题,尤其 T2 ,完全不是LC周赛T2的正常难度水平。
合理推测,如果参赛者不能在10分钟内AC这两道题,那么其实时rank应该不会低于1500...