找到连续赢K场比赛的第一位玩家

2024-10-24

题目:

n 位玩家在进行比赛,玩家编号依次为 0n - 1 。给你一个长度为 n 的整数数组 skills 和一个 整数 k ,其中 skills[i] 是第 i 位玩家的技能等级。skills 中所有整数 互不相同

所有玩家从编号 0n - 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 。

提示:

  • n == skills.length
  • 2 <= n <= 105
  • 1 <= k <= 1e9
  • 1 <= skills[i] <= 106
  • skills 中的整数互不相同。

思路:

直接队列模拟比赛过程即可,为了更加好统计每个人的编号,连续获胜次数,我们需要封装player对象(skill, idx, winCnt)

注意到 k 可能很大,但是 n 最大只有105,所以我们可以根据这个进行剪枝:
	如果 k > n,那么一定是数组中 skill 最大的是最终赢家,直接将它的编号返回即可

代码:

class Solution {
public:
    struct player {
        int skill;
        int idx;
        int winCnt;
        player(int s, int i, int w) {
            skill = s;
            idx = i;
            winCnt = w;
        }
    };
    int findWinningPlayer(vector<int>& skills, int k) {
        // 队列模拟
        queue<player> que;
        int maxIdx = 0, maxValue = skills[0];
        for (int i = 1; i < skills.size(); i++) {
            que.push(player(skills[i], i, 0));
            if (skills[i] > maxValue) {
                maxIdx = i;
                maxValue = skills[i];
            }
        }
        if (k >= skills.size()) return maxIdx;
        player s(skills[0], 0, 0);
        while (true) {
            if (s.winCnt == k) return s.idx;
            player top = que.front();
            que.pop();
            if (s.skill > top.skill) {
                s.winCnt++;
                que.push(top);
            } else {
                que.push(player(s.skill, s.idx, 0));
                s = top;
                s.winCnt++;
            }
        }
        return -1;
    }
};