保龄球游戏的获胜者

标签: 数组 模拟

难度: Easy

给你两个下标从 0 开始的整数数组 player1player2 ,分别表示玩家 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

Submission

运行时间: 32 ms

内存: 16.5 MB

class Solution:
    def isWinner(self, player1: List[int], player2: List[int]) -> int:
        player1_num = 0
        player2_num = 0
        for i in range (0,len(player1)):
            if i > 1:
                if (player1[i-1] == 10) or (player1[i-2] == 10):
                    player1_num += player1[i]*2
                else:
                    player1_num += player1[i]

                if (player2[i-1] == 10) | (player2[i-2] == 10):
                    player2_num += player2[i]*2
                else:
                    player2_num += player2[i]
            elif i == 1:
                if (player1[i-1] == 10):
                    player1_num += player1[i]*2
                else:
                    player1_num += player1[i]

                if (player2[i-1] == 10):
                    player2_num += player2[i]*2
                else:
                    player2_num += player2[i]
            else:
                player1_num += player1[i]
                player2_num += player2[i]
        
        if player1_num > player2_num:
            return 1
        elif player1_num < player2_num:
            return 2
        else:
            return 0
                

Explain

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

时间复杂度: O(n)

空间复杂度: O(1)

class Solution:
    def isWinner(self, player1: List[int], player2: List[int]) -> int:
        player1_num = 0  # 玩家1的总分
        player2_num = 0  # 玩家2的总分
        for i in range(len(player1)):
            if i > 1:
                # 从第三轮开始,检查前两轮是否有满分
                if player1[i-1] == 10 or player1[i-2] == 10:
                    player1_num += player1[i] * 2
                else:
                    player1_num += player1[i]

                if player2[i-1] == 10 or player2[i-2] == 10:
                    player2_num += player2[i] * 2
                else:
                    player2_num += player2[i]
            elif i == 1:
                # 第二轮只需要检查第一轮
                if player1[i-1] == 10:
                    player1_num += player1[i] * 2
                else:
                    player1_num += player1[i]

                if player2[i-1] == 10:
                    player2_num += player2[i] * 2
                else:
                    player2_num += player2[i]
            else:
                # 第一轮直接加分
                player1_num += player1[i]
                player2_num += player2[i]

        if player1_num > player2_num:
            return 1
        elif player1_num < player2_num:
            return 2
        else:
            return 0

Explore

根据题解逻辑,如果玩家在两轮连续得分10,那么第三轮的得分会根据前两轮的得分进行翻倍处理。具体来说,如果第一轮和第二轮都是10分,那么第三轮的得分将会被翻倍。然而,真实的保龄球计分规则中,连续得到10分的情况会有额外的加分,即累积计算前两轮的得分。题解中的处理方式并未完全遵循标准的保龄球计分规则,可能需要调整以更准确地模拟实际游戏。

题解中的代码确实假设了两个数组`player1`和`player2`的长度总是相同,这是因为代码直接使用`len(player1)`作为循环的条件。如果实际情况中两个数组长度不一致,此代码可能会引发错误或不公平的比较。在实际应用中应该首先检查两个数组的长度是否相同,如果不同,则需处理长度不一致的情况,例如通过截取或填充等方式确保比较的公正性。

题解中的算法没有考虑连续三轮或更多轮击中10个瓶子的特殊加分规则,这确实是一个遗漏。在标准保龄球规则中,连续击中10个瓶子会引发更复杂的加分计算,如一次性击倒会使后续两轮的得分都进行加倍。题解中仅考虑了前两轮的得分对当前轮的影响,没有实现更全面的连续加分规则,这可能导致实际得分与应有得分存在偏差。

代码中使用`i > 1`确实能够处理数组长度少于3的情况,因为当数组长度为1或2时,`i > 1`的条件不成立,因此不会执行相关的得分翻倍逻辑。这种方法可以避免数组越界的错误,并且能够适应不同长度的输入。然而,对于边界情况的处理可能不够灵活,特别是如果想要增加更复杂的得分逻辑时,可能需要对代码结构进行调整以更好地适应复杂情况。