leetcode
leetcode 2251 ~ 2300
保龄球游戏的获胜者

保龄球游戏的获胜者

难度:

标签:

题目描述

You are given two 0-indexed integer arrays player1 and player2, that represent the number of pins that player 1 and player 2 hit in a bowling game, respectively.

The bowling game consists of n turns, and the number of pins in each turn is exactly 10.

Assume a player hit xi pins in the ith turn. The value of the ith turn for the player is:

  • 2xi if the player hit 10 pins in any of the previous two turns.
  • Otherwise, It is xi.

The score of the player is the sum of the values of their n turns.

Return

  • 1 if the score of player 1 is more than the score of player 2,
  • 2 if the score of player 2 is more than the score of player 1, and
  • 0 in case of a draw.

 

Example 1:

Input: player1 = [4,10,7,9], player2 = [6,5,2,3]
Output: 1
Explanation: The score of player1 is 4 + 10 + 2*7 + 2*9 = 46.
The score of player2 is 6 + 5 + 2 + 3 = 16.
Score of player1 is more than the score of player2, so, player1 is the winner, and the answer is 1.

Example 2:

Input: player1 = [3,5,7,6], player2 = [8,10,10,2]
Output: 2
Explanation: The score of player1 is 3 + 5 + 7 + 6 = 21.
The score of player2 is 8 + 10 + 2*10 + 2*2 = 42.
Score of player2 is more than the score of player1, so, player2 is the winner, and the answer is 2.

Example 3:

Input: player1 = [2,3], player2 = [4,1]
Output: 0
Explanation: The score of player1 is 2 + 3 = 5
The score of player2 is 4 + 1 = 5
The score of player1 equals to the score of player2, so, there is a draw, and the answer is 0.

 

Constraints:

  • n == player1.length == player2.length
  • 1 <= n <= 1000
  • 0 <= player1[i], player2[i] <= 10

代码结果

运行时间: 32 ms, 内存: 16.5 MB


/*
 思路:
 1. 使用Java Stream API来计算每个玩家的总得分。
 2. 使用一个IntStream来遍历数组,并使用reduce方法计算总得分。
 3. 在计算得分时,检查前两轮的击中瓶数,如果任何一轮的瓶数为10,则当前轮的击中瓶数乘以2。
 4. 比较两个玩家的总得分,返回结果。
 */
import java.util.stream.IntStream;

public class BowlingGameStream {
    public static int findWinner(int[] player1, int[] player2) {
        int score1 = calculateScore(player1);
        int score2 = calculateScore(player2);
        return Integer.compare(score1, score2);
    }

    private static int calculateScore(int[] player) {
        return IntStream.range(0, player.length)
                .map(i -> {
                    if (i >= 2 && (player[i - 1] == 10 || player[i - 2] == 10)) {
                        return 2 * player[i];
                    } else {
                        return player[i];
                    }
                })
                .sum();
    }

    public static void main(String[] args) {
        int[] player1 = {4, 10, 7, 9};
        int[] player2 = {6, 5, 2, 3};
        System.out.println(findWinner(player1, player2)); // 输出: 1
    }
}

解释

方法:

此题解的思路是逐轮计算两位玩家的得分。如果当前轮次大于1(即i>1),则检查前两轮中是否有任意一轮得分为10,若有,则当前轮得分翻倍;如果当前轮次为第二轮(i=1),则只需检查第一轮的得分;如果是第一轮(i=0),直接加当前得分。最后,比较两位玩家的总分,根据得分情况返回胜者。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
如何处理玩家在两轮连续击中10个瓶子的情况?是否有额外的得分规则适用于这种连续得分?
根据题解逻辑,如果玩家在两轮连续得分10,那么第三轮的得分会根据前两轮的得分进行翻倍处理。具体来说,如果第一轮和第二轮都是10分,那么第三轮的得分将会被翻倍。然而,真实的保龄球计分规则中,连续得到10分的情况会有额外的加分,即累积计算前两轮的得分。题解中的处理方式并未完全遵循标准的保龄球计分规则,可能需要调整以更准确地模拟实际游戏。
🦆
如果数组`player1`和`player2`长度不相等,该如何处理?题解中是否假设了两个数组长度总是相同?
题解中的代码确实假设了两个数组`player1`和`player2`的长度总是相同,这是因为代码直接使用`len(player1)`作为循环的条件。如果实际情况中两个数组长度不一致,此代码可能会引发错误或不公平的比较。在实际应用中应该首先检查两个数组的长度是否相同,如果不同,则需处理长度不一致的情况,例如通过截取或填充等方式确保比较的公正性。
🦆
在计算得分时,为何没有考虑连续三轮或更多轮击中10个瓶子的加分规则?这是否遗漏了部分可能的得分情况?
题解中的算法没有考虑连续三轮或更多轮击中10个瓶子的特殊加分规则,这确实是一个遗漏。在标准保龄球规则中,连续击中10个瓶子会引发更复杂的加分计算,如一次性击倒会使后续两轮的得分都进行加倍。题解中仅考虑了前两轮的得分对当前轮的影响,没有实现更全面的连续加分规则,这可能导致实际得分与应有得分存在偏差。
🦆
代码中使用了`i > 1`来判断是否查看前两轮的得分,这种方法是否能有效处理所有边界情况,特别是数组长度少于3的情况?
代码中使用`i > 1`确实能够处理数组长度少于3的情况,因为当数组长度为1或2时,`i > 1`的条件不成立,因此不会执行相关的得分翻倍逻辑。这种方法可以避免数组越界的错误,并且能够适应不同长度的输入。然而,对于边界情况的处理可能不够灵活,特别是如果想要增加更复杂的得分逻辑时,可能需要对代码结构进行调整以更好地适应复杂情况。

相关问题