题目地址
https://leetcode-cn.com/problems/find-the-winner-of-an-array-game/
题目描述
给你一个由 不同 整数组成的整数数组 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
思路
如果胜出场数大于等于数组长度, 那就只能是最大值了,并且这以后最大值被交换到首位,后面的比较都不会发生改变。如果胜出场数小于数组长度,那就只能在一遍遍历中连续胜出目标场次才行,因为一旦失败,较大值交换到首位,后续这个较小值便不可能获胜。
题解
/**
* @Author: vividzcs
* @Date: 2021/2/27 9:38 下午
*/
public class GetWinner {
public static void main(String[] args) {
int[] arr = {2,1,3,5,4,6,7};
int k = 111;
int result = getWinner(arr, k);
System.out.println(result);
result = getWinnerV2(arr, k);
System.out.println(result);
}
private static int getWinnerV2(int[] arr, int k) {
int max = arr[0];
int win = 0;
for (int i=1; i<arr.length && win<k; i++) {
if (max > arr[i]) {
win++;
} else {
max = arr[i];
win = 1;
}
}
return max;
}
/**
* 模仿描述的暴力法
*/
public static int getWinner(int[] arr, int k) {
int len = arr.length;
Map<Integer, Integer> map = new HashMap<>(arr.length);
LinkedList<Integer> list = getLinkedList(arr);
int max = list.removeFirst();
int index = 0;
while (true) {
int current = list.removeFirst();
if (max < current) {
int tmp = max;
max = current;
current = max;
}
list.add(current);
if (!map.containsKey(max)) {
map.put(max, 0);
}
map.put(max, map.get(max) + 1);
if (map.get(max) == k) {
return max;
}
index++;
if (index >= len - 1) {
return max;
}
}
}
private static LinkedList<Integer> getLinkedList(int[] arr) {
LinkedList<Integer> list = new LinkedList<>();
for (int i=0; i<arr.length; i++) {
list.add(arr[i]);
}
return list;
}
}