找到冠军 I

标签: 数组 矩阵

难度: Easy

一场比赛中共有 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 队将会是 冠军

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

示例 1:

输入:grid = [[0,1],[0,0]]
输出:0
解释:比赛中有两支队伍。
grid[0][1] == 1 表示 0 队比 1 队强。所以 0 队是冠军。

示例 2:

输入:grid = [[0,0,1],[1,0,1],[0,0,0]]
输出:1
解释:比赛中有三支队伍。
grid[1][0] == 1 表示 1 队比 0 队强。
grid[1][2] == 1 表示 1 队比 2 队强。
所以 1 队是冠军。

提示:

  • 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 队强

Submission

运行时间: 30 ms

内存: 16.7 MB

class Solution:
    def findChampion(self, grid: List[List[int]]) -> int:
        for i,x in enumerate(grid):
            if x.count(0) == 1:
                return i

Explain

题解的核心思路是检查每支队伍是否可能是冠军队伍。根据题目,一支队伍成为冠军的条件是没有其他队伍比它强。在给定的二维布尔矩阵grid中,grid[i][j]为1表示队伍i比队伍j强。因此,对于任意队伍i来说,如果它的行中只有一个0(即它自己与自己的对比,grid[i][i]总是0),那么意味着没有其他队伍能击败它,从而它可能是冠军。因此,算法遍历每一行,计算0的数量,如果某行中0的数量正好为1,那么这支队伍就可能是冠军,直接返回这支队伍的索引。

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

空间复杂度: O(1)

class Solution:
    def findChampion(self, grid: List[List[int]]) -> int:
        for i, x in enumerate(grid):
            # 计算第i行中0的数量
            if x.count(0) == 1:
                # 如果只有一个0,即只有自己与自己比赛为0,那么队伍i可能是冠军
                return i

Explore

题解中的算法假设最多只有一支队伍满足成为冠军的条件,即在其它所有队伍都无法击败它的情况下,这支队伍的行中只有一个0(即自己与自己的比赛)。如果实际情况中出现多个队伍的行都只有一个0,这在逻辑上表明题目的输入数据可能存在错误或条件描述不完整,因为按照题目的定义,只能有一支队伍满足没有其他队伍比它强的条件。在现实比赛和符合题目描述的逻辑中,这种情况不应当发生。

在给定的比赛规则下,如果一个队伍i的对应行中只有一个0(即grid[i][i],自己与自己比),并且其它位置都为1(表示队伍i击败了所有其他队伍),则自然意味着没有其他队伍能击败队伍i。这样,只需检查每个队伍的行中0的数量,就可以直接判断出是否存在一支队伍击败了所有其它队伍,从而确定它为冠军。这是因为grid的定义直接反映了比赛结果,每行的1表示胜利关系,而0的唯一合法位置在对角线上,表示自己与自己的比较。

在此题设定的比赛规则中,grid[i][i]表示队伍i与自己的比较结果,逻辑上队伍不能与自己比赛,因此这一位置应当被定义为0,表示没有比赛发生。这是一个常规的设定,用于简化比赛结果的矩阵表示。实际应用中,除非比赛规则另有特殊说明或定义,grid[i][i]通常总是设为0。没有理由或实际情况下,队伍与自己的比赛结果设为1或其他值。