比赛的赢家 | 豆包MarsCode AI刷题

41 阅读3分钟

问题描述

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

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

思路分析

  1. 问题本质

    • 需要模拟一个比赛过程,直到某个整数连续赢得 k 次。
    • 由于数组中的元素互不相同,比赛过程中不会出现平局。
  2. 解决方案

    • 初始化变量

      • winner:记录当前的赢家。
      • consecutiveWins:记录当前赢家连续获胜的次数。
    • 特殊情况处理

      • 如果 k 大于等于数组的长度减1(即 k >= n - 1),那么比赛的赢家一定是数组中的最大值,因为最大值在前 n-1 回合中会连续获胜。
    • 模拟比赛

      • 从左到右遍历数组,模拟每回合的比赛:

        • 如果 arr[i] 大于 winner,更新 winner 为 arr[i],重置 consecutiveWins 为1。
        • 否则,consecutiveWins 增加1。
      • 如果 consecutiveWins 达到 k,返回 winner

代码详解


import java.util.Arrays;

public class Main {
    public static int solution(int[] arr, int k) {
        int n = arr.length;
        int winner = arr[0];
        int consecutiveWins = 0;

        // 如果 k 大于等于数组长度减1,直接返回数组中的最大值
        if (k >= n - 1) {
            int max = arr[0];
            for (int i = 1; i < n; i++) {
                if (arr[i] > max) {
                    max = arr[i];
                }
            }
            return max;
        }

        // 模拟比赛过程
        for (int i = 1; i < n; i++) {
            if (arr[i] > winner) {
                winner = arr[i];
                consecutiveWins = 1;
            } else {
                consecutiveWins++;
            }

            // 如果某个整数连续赢得 k 次,返回该整数
            if (consecutiveWins == k) {
                return winner;
            }
        }

        return winner;
    }

    public static void main(String[] args) {
        int[] arr1 = {2, 1, 3, 5, 4, 6, 7, 9};
        System.out.println(solution(arr1, 2) == 5);

        int[] arr2 = {3, 2, 1, 4};
        System.out.println(solution(arr2, 10) == 4);

        int[] arr3 = {1, 9, 8, 7, 6, 5, 4, 3, 2, 11};
        System.out.println(solution(arr3, 7) == 9);
    }
}

知识总结

  1. 贪心算法

    • 贪心算法是一种在每个步骤中都选择当前最优解的算法,适用于某些特定的优化问题。
    • 在这个问题中,通过逐步更新赢家和连胜次数,可以高效地找到最终的赢家。
  2. 条件判断

    • 使用 if 语句来判断当前元素是否大于赢家,以及连胜次数是否达到 k
    • 通过 Math.max 函数来更新最大值,确保特殊情况处理的正确性。
  3. 数组操作

    • 使用数组的索引来访问和更新元素。
    • 通过 for 循环遍历数组,模拟比赛过程。
  4. 代码优化

    • 通过处理特殊情况(k >= n - 1),可以提前返回结果,提高代码的效率。
    • 在 main 函数中添加更多的测试用例,确保代码的正确性和鲁棒性。

个人理解与学习建议

  1. 理解贪心算法

    • 贪心算法在每一步中选择当前最优解,最终达到全局最优解。通过这个题目,可以加深对贪心算法的理解和应用。
  2. 代码可读性

    • 使用有意义的变量名,如 winnerconsecutiveWins 等,可以提高代码的可读性。
    • 添加注释,解释每一步的逻辑,有助于他人理解代码。
  3. 测试用例

    • 在 main 函数中添加更多的测试用例,确保代码的正确性和鲁棒性。
    • 测试用例应涵盖各种边界情况和特殊输入,确保代码在所有情况下都能正确运行。
  4. 学习建议

    • 多做练习:通过多做类似的题目,可以提高对贪心算法的理解和应用能力。
    • 思考边界情况:在编写代码时,思考各种边界情况,确保代码的鲁棒性。
    • 代码模块化:将代码分成多个函数或模块,可以提高代码的可维护性和可读性。