题目描述:
给你一个由 不同 整数组成的整数数组 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回合:
- 比较
[2, 1]
->2
赢,1
移至末尾 - 更新数组:
[2, 3, 5, 4, 6, 7, 1]
- 比较
- 第2回合:
- 比较
[2, 3]
->3
赢,2
移至末尾 - 更新数组:
[3, 5, 4, 6, 7, 1, 2]
- 连胜次数重置为 1(因为
3
是新的赢家)
- 比较
- 第3回合:
- 比较
[3, 5]
->5
赢,3
移至末尾 - 更新数组:
[5, 4, 6, 7, 1, 2, 3]
- 连胜次数重置为 1(因为
5
是新的赢家)
- 比较
- 第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回合:
- 比较
[3, 2]
->3
赢,2
移至末尾 - 更新数组:
[3, 1, 2]
- 连胜次数为 1
- 比较
- 第2回合:
- 比较
[3, 1]
->3
赢,1
移至末尾 - 更新数组:
[3, 2, 1]
- 连胜次数为 2
- 比较
- ...
由于 k
是 10,只要 3
能继续连胜(因数组是 3, 2, 1
以循环的顺序比较),3
会一直赢下去。因此 3
将是赢家。
示例 3 详细分析:
输入:arr = [1, 9, 8, 2, 3, 7, 6, 4, 5]
, k = 7
输出:9
解释:
- 第1回合:
- 比较
[1, 9]
->9
赢,1
移至末尾 - 更新数组:
[9, 8, 2, 3, 7, 6, 4, 5, 1]
- 连胜次数为 1
- 比较
- 第2回合:
- 比较
[9, 8]
->9
赢,8
移至末尾 - 更新数组:
[9, 2, 3, 7, 6, 4, 5, 1, 8]
- 连胜次数为 2
- 比较
- ...
一直进行到 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)
因为只使用了常数的额外空间。
- 时间复杂度:最坏情况下为
解题思路:
方法描述:
-
初始化参数:
currentWinner
设置为arr[0]
,记录当前的赢家。consecutiveWins
初始化为0
,记录当前赢家的连胜次数。
-
遍历数组:
- 从数组索引
1
开始遍历数组。 - 在每次比较中:
- 如果
arr[i]
大于currentWinner
,更新currentWinner
并重置consecutiveWins
。 - 否则,增加
consecutiveWins
的值。
- 如果
- 从数组索引
-
胜利判断:
- 一旦
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
}
}
知识点解析:
-
数组的使用:问题中涉及到一个整数数组
arr
,我们需要遍历这个数组来找到游戏的胜者。数组是存储固定大小的同类型元素序列,是最基础的数据结构之一。 -
循环控制:为了比较数组中的每个元素,我们使用了
for
循环从数组的第二个元素开始遍历,直至数组末尾。 -
条件判断:在每次循环中,我们使用
if-else
语句来判断当前元素(挑战者)与当前赢家的大小,以及是否连续赢得了k
次比赛。 -
变量的使用:我们使用变量
currentWinner
来跟踪当前的赢家,以及变量consecutiveWins
来记录当前赢家连续赢得比赛的次数。 -
逻辑运算:通过比较操作(
>
)来决定每回合的赢家,以及通过逻辑判断(consecutiveWins == k
)来确定是否结束游戏。 -
返回值:方法
getWinner
通过return
语句返回游戏的胜者。
知识点 | 详细说明 |
---|---|
数组 | 使用数组存储游戏每个回合的参与者 |
循环控制 | 通过 for 循环遍历数组中的元素 |
条件判断 | 使用 if-else 语句判断赢家以及游戏是否结束 |
变量使用 | 利用变量记录当前赢家和连胜次数 |
逻辑运算 | 运用比较运算符和等式判断来决定赢家和游戏结束条件 |
返回值 | 使用 return 语句返回游戏的胜者 |
2024.5.23