题目:
给你两个下标从 0 开始的整数数组 player1
和 player2
,分别表示玩家 1 和玩家 2 击中的瓶数。
保龄球比赛由 n
轮组成,每轮的瓶数恰好为 10
。
假设玩家在第 i
轮中击中 xi
个瓶子。玩家第 i
轮的价值为:
- 如果玩家在该轮的前两轮的任何一轮中击中了
10
个瓶子,则为2xi
。 - 否则,为
xi
。
玩家的得分是其 n
轮价值的总和。
返回
- 如果玩家 1 的得分高于玩家 2 的得分,则为
1
; - 如果玩家 2 的得分高于玩家 1 的得分,则为
2
; - 如果平局,则为
0
。
示例 1:
输入:player1 = [4,10,7,9], player2 = [6,5,2,3] 输出:1 解释:player1 的得分是 4 + 10 + 2*7 + 2*9 = 46 。 player2 的得分是 6 + 5 + 2 + 3 = 16 。 player1 的得分高于 player2 的得分,所以 play1 在比赛中获胜,答案为 1 。
示例 2:
输入:player1 = [3,5,7,6], player2 = [8,10,10,2] 输出:2 解释:player1 的得分是 3 + 5 + 7 + 6 = 21 。 player2 的得分是 8 + 10 + 2*10 + 2*2 = 42 。 player2 的得分高于 player1 的得分,所以 play2 在比赛中获胜,答案为 2 。
示例 3:
输入:player1 = [2,3], player2 = [4,1] 输出:0 解释:player1 的得分是 2 + 3 = 5 。 player2 的得分是 4 + 1 = 5 。 player1 的得分等于 player2 的得分,所以这一场比赛平局,答案为 0 。
提示:
n == player1.length == player2.length
1 <= n <= 1000
0 <= player1[i], player2[i] <= 10
题解:
- 初始化总得分: 对于两个玩家各自初始化一个总得分变量。
- 遍历轮次: 从第1轮到第n轮,对于每一轮,检查前两轮是否有击中10个瓶子。
- 计算得分: 如果前两轮中有任意一轮击中了10个瓶子,则当前轮次的得分翻倍;否则得分不变。
- 累加总得分: 将每轮的得分累计到总得分中。
- 比较总得分: 最后比较两个玩家的总得分,决定返回的结果。
流程图说明:
+---------------------------------------+
| 开始 |
+---------------------------------------+
| 初始化 player1_score 和 player2_score |
| 均为 0 |
+---------------------------------------+
| 循环 i 从 0 到 n-1(n 为轮次数): |
| +-----------------------------------+|
| | a. 检查 player1 过去两轮是否有击中 10 |
| | 个瓶子: |
| | 如果有,player1 当前轮次分数 * 2 |
| | 如果没有,player1 当前轮次分数保持 |
| | 不变 |
| | b. 更新 player1 的总分数 |
| +-----------------------------------+|
| | c. 检查 player2 过去两轮是否有击中 10 |
| | 个瓶子: |
| | 如果有,player2 当前轮次分数 * 2 |
| | 如果没有,player2 当前轮次分数保持 |
| | 不变 |
| | d. 更新 player2 的总分数 |
| +-----------------------------------+|
| 循环结束 |
+---------------------------------------+
| 比较 player1_score 和 player2_score |
+---------------------------------------+
| 返回赢者 (1或2) 或 平局 (0) |
+---------------------------------------+
| 结束 |
+---------------------------------------+
代码:
class Solution {
public int isWinner(int[] player1, int[] player2) {
// 分别计算每个玩家的总得分
int player1Score = calculateScore(player1);
int player2Score = calculateScore(player2);
// 比较玩家的得分并返回结果
if (player1Score > player2Score) {
return 1;
} else if (player2Score > player1Score) {
return 2;
} else {
return 0;
}
}
// 计算指定玩家的总得分
private int calculateScore(int[] player) {
int n = player.length;
int score = 0;
for (int i = 0; i < n; i++) {
if ((i >= 1 && player[i - 1] == 10) || (i >= 2 && player[i - 2] == 10)) {
score += 2 * player[i];
} else {
score += player[i];
}
}
return score;
}
}
解释代码的核心部分:
isWinner
方法用来比较两个玩家的得分,并根据最终结果返回1, 2或者0。calculateScore
方法根据题目规则计算每个玩家的总得分,分步骤地检查前两轮是否有击中10个瓶子。- 双重检查前两轮的状态,这样可以确保我们正确地判断当前轮次的得分是否需要翻倍。
通过这种方法,能够准确地计算出每个玩家在保龄球比赛中的得分,并确定最终的比赛结果。
知识点解析:
1. 数组操作
本代码主要操作对象是两个整数数组 player1
和 player2
。数组是用于存储相同类型元素的集合,并且可以通过下标(索引)访问每个元素。代码中多个地方都使用了数组的访问和遍历。
2. 循环与条件判断
代码中使用了for循环来遍历数组以及条件判断语句(if-else)来决定每轮得分是否需要翻倍。
3. 方法调用
代码中定义了两个方法:isWinner
和 calculateScore
。一个方法是main方法,用于主逻辑控制;另一个是辅助方法,用于计算得分。方法之间的相互调用体现了代码的模块化,提高了代码的可读性和复用性。
4. 算法思想
代码的算法思想主要是通过累加得分的方式来实现得分的计算。这种思想也是许多动态规划和循环累加问题中的基础。
知识点 | 代码行数 | 解释 |
---|---|---|
数组声明与初始化 | 2, 3 | 定义并初始化玩家1和玩家2的数组 int[] player1 和 int[] player2 。 |
数组访问 | 5, 6, 14 | 通过下标访问数组元素 player1[i] 和 player2[i] 。 |
for循环 | 12-16 | 使用 for 循环遍历每个玩家的数组,以计算每轮的得分。 |
条件判断 | 14-15 | 使用 if-else 语句判断当前轮的得分是否需要翻倍。 |
方法定义 | 1, 9 | 定义两个方法 isWinner 和 calculateScore 。 |
方法调用 | 5, 6 | 在 isWinner 方法中调用辅助方法 calculateScore 。 |
算法思想 | 整体代码 | 通过累加每轮得分来计算总得分,并根据前两轮的情况进行判断和加倍处理。 |