一场比赛中共有 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
队将会是 冠军 。
返回这场比赛中将会成为冠军的队伍。
示例 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]
的值为0
或1
- 对于所有
i
,grid[i][i]
等于0.
- 对于满足
i != j
的所有i, j
,grid[i][j] != grid[j][i]
均成立 - 生成的输入满足:如果
a
队比b
队强,b
队比c
队强,那么a
队比c
队强
最容易想到的方法就是遍历grid数组,按照题目的逻辑,冠军队伍那一行仅有i = j时,数字为0,其余均为1。
这种方式的时间复杂度为O(n^2)。
如何优化遍历次数?
考虑每行中,如果遇到0,且i != j,那就说明 j 比 i 强,此时就可以跳出 i 行的循环了。这样可以减少遍历次数,但仍不是最少的。
使用擂台法,并以 j 作为champion
这样在每行中只需要查找一个元素,即grid[ i ][champion],如果这个值为1,说明 i 比champion强,更新champion,如果为0,就查找下一行。直到所有行遍历完成,champion中保留的就是冠军。
时间复杂度O(n)。
代码:
class Solution {
public:int findChampion(vector<vector<int>>& grid) {int n = grid.size();int champion = 0;for(int i = 0;i < n;i++){if(grid[i][champion] == 1){champion = i;}}return champion;}
};