AI刷题-比赛的赢家 | 青训营笔记

116 阅读4分钟

问题描述

小M正在玩一个数组比赛游戏,游戏规则如下:每回合游戏都在所有元素互不相同的数组 arr 的前两个元素 arr[0] 和 arr[1] 之间进行。较大的整数将会取得这一回合的胜利并保留在位置 0,而较小的整数则会被移至数组的末尾。比赛继续,直到某个整数连续赢得 k 次,这个整数即为比赛的赢家。

给定一个整数数组 arr 和一个整数 k,请你返回赢得比赛的整数。题目数据保证游戏中一定存在赢家。


测试样例

样例1:

输入:arr = [2, 1, 3, 5, 4, 6, 7, 9],k = 2
输出:5

样例2:

输入:arr = [3, 2, 1, 4],k = 10
输出:4

样例3:

输入:arr = [1, 9, 8, 7, 6, 5, 4, 3, 2, 11],k = 7
输出:9

问题分析

在这个问题中,我们需要模拟一个比赛的过程,直到某个整数连续赢得 k 次,成为比赛的赢家。比赛的规则是:

  • 每回合比赛都发生在数组的前两个元素之间,较大的元素胜利并留在数组的前面,而较小的元素被移到数组的末尾。
  • 这个过程持续进行,直到某个整数连续赢得 k 次。

问题的特点:

  • 每回合的比赛只发生在数组的前两个元素,较大的元素继续保留在数组的前面,较小的被移到末尾。
  • 我们只关心谁赢得了连续的 k 次。题目保证一定会有一个赢家。
  • 数组的前两个元素会影响比赛的胜负,所以数组的状态会不断变化。比赛的过程类似于一个模拟操作。

思路分析

  1. 游戏模拟

    • 在每一轮比赛中,比较 arr[0]arr[1]。较大的数会继续留在数组的前面,较小的数会被移到数组的末尾。
    • 记录谁连续赢得了多少次比赛。
    • 一旦某个元素连续赢得了 k 次,就可以停止比赛,返回这个元素作为赢家。
  2. 如何记录胜利次数

    • 我们使用一个变量 current_winner 来跟踪当前胜利的元素。
    • 使用一个变量 win_streak 来记录当前元素的连续胜利次数。
    • 如果当前元素的连续胜利次数达到了 k,则返回这个元素作为比赛的赢家。
  3. 循环模拟

    • 我们用一个 while 循环来不断进行比赛,直到某个元素连续赢得 k 次。
    • 每次比赛结束后,更新数组的状态,并根据比赛结果更新 current_winnerwin_streak

代码实现

python
Copy code
def arrayGame(arr, k):
    # 初始化
    current_winner = None  # 当前连续获胜的元素
    win_streak = 0  # 当前元素的连续获胜次数
    
    # 模拟比赛
    while True:
        # 比较前两个元素
        if arr[0] > arr[1]:
            winner = arr[0]
            arr.append(arr[1])  # arr[1] 被移到数组末尾
            arr[1] = arr[0]  # arr[0] 保留在数组的前面
        else:
            winner = arr[1]
            arr.append(arr[0])  # arr[0] 被移到数组末尾
            arr[0] = arr[1]  # arr[1] 保留在数组的前面
        
        # 检查胜利者是否是之前的胜利者
        if winner == current_winner:
            win_streak += 1
        else:
            current_winner = winner
            win_streak = 1  # 重置连续胜利次数为 1
        
        # 如果有元素连续赢得 k 次比赛,返回该元素
        if win_streak == k:
            return current_winner

解释:

  1. 初始化

    • current_winner 用来记录当前连续获胜的元素。
    • win_streak 用来记录当前元素的连续获胜次数。
  2. 循环模拟比赛

    • 每次比赛时,比较 arr[0]arr[1],较大的数留在前面,较小的数移动到末尾。
    • 如果当前获胜者与之前的获胜者相同,增加 win_streak。如果不同,更新 current_winner 并将 win_streak 设为 1。
  3. 检查胜者

    • 如果某个元素的连续胜利次数达到了 k,则返回该元素作为赢家。

时间复杂度分析

  • 时间复杂度:每一轮比赛会根据规则更新数组中的元素位置,最多进行 O(n) 轮比赛,其中 n 是数组的长度。在最坏情况下,循环将执行直到某个元素连续获胜 k 次,因此时间复杂度为 O(n * k)
  • 空间复杂度:只使用了常数额外空间来存储 current_winnerwin_streak,因此空间复杂度为 O(1)

总结

这个问题通过模拟比赛的过程,利用数组前两个元素的比较和交换来决定每轮比赛的胜负,并且实时追踪胜利者的连续获胜次数,直到某个元素达到 k 次连续胜利。