题目描述
有 n
位玩家在进行比赛,玩家编号依次为 0
到 n - 1
。
给你一个长度为 n
的整数数组 skills
和一个 正整数 k
,其中 skills[i]
是第 i
位玩家的技能等级。skills
中所有整数 互不相同 。
所有玩家从编号 0
到 n - 1
排成一列。
比赛进行方式如下:
队列中最前面两名玩家进行一场比赛,技能等级 更高 的玩家胜出。
比赛后,获胜者保持在队列的开头,而失败者排到队列的末尾。
这个比赛的赢家是 第一位连续 赢下 k 场比赛的玩家。
请你返回这个比赛的赢家编号。
样例1
输入:skills = [4,2,6,3,9], k = 2
输出:2
解释:
一开始,队列里的玩家为 [0,1,2,3,4] 。比赛过程如下:
玩家 0 和 1 进行一场比赛,玩家 0 的技能等级高于玩家 1 ,玩家 0 胜出,队列变为 [0,2,3,4,1] 。
玩家 0 和 2 进行一场比赛,玩家 2 的技能等级高于玩家 0 ,玩家 2 胜出,队列变为 [2,3,4,1,0] 。
玩家 2 和 3 进行一场比赛,玩家 2 的技能等级高于玩家 3 ,玩家 2 胜出,队列变为 [2,4,1,0,3] 。
玩家 2 连续赢了 k = 2 场比赛,所以赢家是玩家 2 。
样例2
输入:skills = [2,5,4], k = 3
输出:1
解释:
一开始,队列里的玩家为 [0,1,2] 。比赛过程如下:
玩家 0 和 1 进行一场比赛,玩家 1 的技能等级高于玩家 0 ,玩家 1 胜出,队列变为 [1,2,0] 。
玩家 1 和 2 进行一场比赛,玩家 1 的技能等级高于玩家 2 ,玩家 1 胜出,队列变为 [1,0,2] 。
玩家 1 和 0 进行一场比赛,玩家 1 的技能等级高于玩家 0 ,玩家 1 胜出,队列变为 [1,2,0] 。
玩家 1 连续赢了 k = 3 场比赛,所以赢家是玩家 1 。
算法
(模拟) $O(n)$
- 如果
k
超过了n
,则最后的结果一定是数组中的最大值,所以我们这里直接令k = n
- 定义三个变量,
i
用来循环遍历数组,j
用来记录前面遍历后的最大值的下标,cnt
用来记录j
位置上的值比较成功的次数 - 当
skills[i] >= skills[j]
时,我们让记录最大值的下标j = i
,并且cnt
置1
,否则cnt++
- 当
cnt == k
时,返回j
- 更新
i
的值:i = (i + 1) % n
C++ 代码
class Solution {
public:
int findWinningPlayer(vector<int>& skills, int k) {
int n = skills.size();
if (k > n) k = n;
int i = 1, cnt = 0, j = 0;
while (true) {
if (skills[j] <= skills[i]) {
cnt = 1;
j = i;
} else cnt++;
if (k == cnt) return j;
i = (i + 1) % n;
}
return 0;
}
};