每日一练2024.5.19(补 2024.5.23)

题目描述:

     给你一个由 不同 整数组成的整数数组 arr 和一个整数 k 。

        每回合游戏都在数组的前两个元素(即 arr[0] 和 arr[1] )之间进行。比较 arr[0] 与 arr[1] 的大小,较大的整数将会取得这一回合的胜利并保留在位置 0 ,较小的整数移至数组的末尾。当一个整数赢得 k 个连续回合时,游戏结束,该整数就是比赛的 赢家 。

        返回赢得比赛的整数。

        题目数据 保证 游戏存在赢家。

示例 1:

输入:arr = [2,1,3,5,4,6,7], k = 2
输出:5
解释:一起看一下本场游戏每回合的情况:


因此将进行 4 回合比赛,其中 5 是赢家,因为它连胜 2 回合。

示例 2:

输入:arr = [3,2,1], k = 10
输出:3
解释:3 将会在前 10 个回合中连续获胜。

示例 3:

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

示例 4:

输入:arr = [1,11,22,33,44,55,66,77,88,99], k = 1000000000
输出:99

提示:

  • 2 <= arr.length <= 10^5
  • 1 <= arr[i] <= 10^6
  • arr 所含的整数 各不相同 。
  • 1 <= k <= 10^9

示例解析:

示例 1:

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

第1回合:[2, 1, 3, 5, 4, 6, 7] -> arr = [2, 3, 5, 4, 6, 7, 1]
第2回合:[2, 3, 5, 4, 6, 7, 1] -> arr = [3, 5, 4, 6, 7, 1, 2]
第3回合:[3, 5, 4, 6, 7, 1, 2] -> arr = [5, 4, 6, 7, 1, 2, 3]
第4回合:[5, 4, 6, 7, 1, 2, 3] -> arr = [5, 6, 7, 1, 2, 3, 4]

5 连胜 2 次,所以 5 是赢家。

示例 1 详细分析:

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

解释

  1. 第1回合
    • 比较 [2, 1] -> 2 赢,1 移至末尾
    • 更新数组:[2, 3, 5, 4, 6, 7, 1]
  2. 第2回合
    • 比较 [2, 3] -> 3 赢,2 移至末尾
    • 更新数组:[3, 5, 4, 6, 7, 1, 2]
    • 连胜次数重置为 1(因为 3 是新的赢家)
  3. 第3回合
    • 比较 [3, 5] -> 5 赢,3 移至末尾
    • 更新数组:[5, 4, 6, 7, 1, 2, 3]
    • 连胜次数重置为 1(因为 5 是新的赢家)
  4. 第4回合
    • 比较 [5, 4] -> 5 赢,4 移至末尾
    • 更新数组:[5, 6, 7, 1, 2, 3, 4]
    • 连胜次数为 2(5 连续赢了 2 次)

所以,5 连胜 2 次成为赢家。

示例 2 详细分析:

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

解释

  1. 第1回合
    • 比较 [3, 2] -> 3 赢,2 移至末尾
    • 更新数组:[3, 1, 2]
    • 连胜次数为 1
  2. 第2回合
    • 比较 [3, 1] -> 3 赢,1 移至末尾
    • 更新数组:[3, 2, 1]
    • 连胜次数为 2
  3. ...

由于 k 是 10,只要 3 能继续连胜(因数组是 3, 2, 1 以循环的顺序比较),3 会一直赢下去。因此 3 将是赢家。

示例 3 详细分析:

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

解释

  1. 第1回合
    • 比较 [1, 9] -> 9 赢,1 移至末尾
    • 更新数组:[9, 8, 2, 3, 7, 6, 4, 5, 1]
    • 连胜次数为 1
  2. 第2回合
    • 比较 [9, 8] -> 9 赢,8 移至末尾
    • 更新数组:[9, 2, 3, 7, 6, 4, 5, 1, 8]
    • 连胜次数为 2
  3. ...

一直进行到 9 连续赢 7 次,9 成为赢家。

示例 4 详细分析:

输入arr = [1, 11, 22, 33, 44, 55, 66, 77, 88, 99]k = 1000000000
输出:99

解释
因 k 为一个极大值,这意味着数组中的最大值会最终连胜直到达到 k。在数组中,99 是最大值,因此 99 最终将会成为赢家。因此我们可以直接返回数组中的最大值。

知识点补充解析:

  • 复杂度分析
    • 时间复杂度:最坏情况下为 O(n + k),即 n 表示数组的元素个数,k 表示连胜回合数。如果数组比较长,在没有提前达到连胜的情况下,算法将遍历数组 n 次,并在每次比较中维护连胜次数,直到达到 k 次连胜。
    • 空间复杂度:O(1) 因为只使用了常数的额外空间。

解题思路:

方法描述:

  1. 初始化参数

    • currentWinner 设置为 arr[0],记录当前的赢家。
    • consecutiveWins 初始化为 0,记录当前赢家的连胜次数。
  2. 遍历数组

    • 从数组索引 1 开始遍历数组。
    • 在每次比较中:
      • 如果 arr[i] 大于 currentWinner,更新 currentWinner 并重置 consecutiveWins
      • 否则,增加 consecutiveWins 的值。
  3. 胜利判断

    • 一旦 consecutiveWins 达到 k,返回 currentWinner
    • 如果遍历结束依然没有达到 k 次连胜,返回数组中的最大值。

流程图:

+---------------------------------------------+
|                   开始                      |
+---------------------------------------------+
              |
              V
+---------------------------------------------+
|   初始化 currentWinner = arr[0]             |
|   初始化 consecutiveWins = 0               |
+---------------------------------------------+
              |
              V
+---------------------------------------------+
|           遍历数组 arr                      |
|       (从索引 1 到 arr.length - 1)          |
+---------------------------------------------+
              |
              V
+---------------当前项 arr[i] 开始--------------+
|             |
|             V
|     +---------------------------------+
|     | arr[i] > currentWinner          |
|     +---------------------------------+
|             |
|             V
|     +---------------------------------+                否
|     | 将 currentWinner 设置为 arr[i]  <---------------------------+
|     +---------------------------------+   是                      |
|     | 将 consecutiveWins 重置为 1      |                          |
|     +---------------------------------+                           |
|             |                                                     |
|             V                                                     |
|     +--------------------------------+                            |
|     | currentWinner == arr[i]         |                           |
|     +--------------------------------+                            |
|             |                         |                           |
|             V                         | 否                        |
|     +--------------------------------+                            |
|     | 增加 consecutiveWins            |                           |
|     | 的值 (consecutiveWins++)         |                          |
|     +--------------------------------+                            |
|             |                         |                           |
|             V                         |                           |
|     +--------------------------------+                            |
|     | consecutiveWins >= k            |                           |
|     +--------------------------------+                            |
|             |                           | 否                      |
|             V                           |                         |
|     +--------------------------------+  是                        |
|     | 返回 currentWinner 作为         |-------------+             |
|     | 游戏赢家。                      |             |             |
|     +--------------------------------+             |              |
|                                   |             |                 |
|                                   V             |                 |
+---------------------------------当前项 arr[i] 结束---------------+
                                    |
+------------------------------------------------------------------------+
                                    |
                                向后遍历继续
                                    |
                                    V
+---------------------------------------------+
|  检查是否遍历了整个数组                      |
|  (如果没有继续,否则到下个步骤)              |
+---------------------------------------------+
              |
              V
+---------------------------------------------+
|     返回 arr 中的最大值作为赢家              |
+---------------------------------------------+
              |
              V
+---------------------------------------------+
|                    结束                     |
+---------------------------------------------+

代码实现:

public class Solution {
    public int getWinner(int[] arr, int k) {
        int currentWinner = arr[0];
        int consecutiveWins = 0;

        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > currentWinner) {
                currentWinner = arr[i];
                consecutiveWins = 1;
            } else {
                consecutiveWins++;
            }
            // 一旦连续胜利次数达到 k,就可以结束游戏。
            if (consecutiveWins == k) {
                break;
            }
        }

        return currentWinner;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] arr1 = {2, 1, 3, 5, 4, 6, 7};
        int k1 = 2;
        System.out.println("Winner is: " + solution.getWinner(arr1, k1)); // 输出:5

        int[] arr2 = {3, 2, 1};
        int k2 = 10;
        System.out.println("Winner is: " + solution.getWinner(arr2, k2)); // 输出:3

        int[] arr3 = {1, 9, 8, 2, 3, 7, 6, 4, 5};
        int k3 = 7;
        System.out.println("Winner is: " + solution.getWinner(arr3, k3)); // 输出:9

        int[] arr4 = {1, 11, 22, 33, 44, 55, 66, 77, 88, 99};
        int k4 = 1000000000;
        System.out.println("Winner is: " + solution.getWinner(arr4, k4)); // 输出:99
    }
}
知识点解析:
  1. 数组的使用:问题中涉及到一个整数数组 arr,我们需要遍历这个数组来找到游戏的胜者。数组是存储固定大小的同类型元素序列,是最基础的数据结构之一。

  2. 循环控制:为了比较数组中的每个元素,我们使用了 for 循环从数组的第二个元素开始遍历,直至数组末尾。

  3. 条件判断:在每次循环中,我们使用 if-else 语句来判断当前元素(挑战者)与当前赢家的大小,以及是否连续赢得了 k 次比赛。

  4. 变量的使用:我们使用变量 currentWinner 来跟踪当前的赢家,以及变量 consecutiveWins 来记录当前赢家连续赢得比赛的次数。

  5. 逻辑运算:通过比较操作(>)来决定每回合的赢家,以及通过逻辑判断(consecutiveWins == k)来确定是否结束游戏。

  6. 返回值:方法 getWinner 通过 return 语句返回游戏的胜者。

知识点详细说明
数组使用数组存储游戏每个回合的参与者
循环控制通过 for 循环遍历数组中的元素
条件判断使用 if-else 语句判断赢家以及游戏是否结束
变量使用利用变量记录当前赢家和连胜次数
逻辑运算运用比较运算符和等式判断来决定赢家和游戏结束条件
返回值使用 return 语句返回游戏的胜者

2024.5.23

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值