LeetCode "Maximum Points You Can Obtain from Cards" python 代码不起作用,我需要显示为什么



我在理解我的代码在LeetCode问题上的问题时遇到了问题,"您可以从卡中获得的最大点数";

首先,我将在这里发布问题:


有几张牌排成一行,每张牌都有相关的点数。点数在整数数组cardPoints中给出。

在一个步骤中,您可以从该行的开头或末尾取出一张卡。你必须准确地拿k张牌。

你的分数是你所拿牌的分数之和。

给定整数数组cardPoints和整数k,返回您可以获得的最大分数。

示例1:

Input: cardPoints = [1,2,3,4,5,6,1], k = 3
Output: 12
Explanation: After the first step, your score will always be 1. However, choosing the rightmost card first will maximize your total score. The optimal strategy is to take the three cards on the right, giving a final score of 1 + 6 + 5 = 12.

示例2:

Input: cardPoints = [2,2,2], k = 2
Output: 4
Explanation: Regardless of which two cards you take, your score will always be 4.

示例3:

Input: cardPoints = [9,7,7,9,7,7,9], k = 7
Output: 55
Explanation: You have to take all the cards. Your score is the sum of points of all cards.

示例4:

Input: cardPoints = [1,1000,1], k = 1
Output: 1
Explanation: You cannot take the card in the middle. Your best score is 1. 

示例5:

Input: cardPoints = [1,79,80,1,1,1,200,1], k = 3
Output: 202

限制条件:

1 <= cardPoints.length <= 10^5

1 <= cardPoints[i] <= 10^4

1 <= k <= cardPoints.length


这里有一个链接到leetcode上的问题:

https://leetcode.com/problems/maximum-points-you-can-obtain-from-cards

如果你熟悉这个问题,你可能会明白,最好的方法是使用滑动窗口。

我理解这一点,并能够使一个版本发挥作用。但我的第一次尝试是强行通过,检查列表中的第一个和最后一个项目,取最大值,然后将其从列表中弹出。

这是我使用的代码:

class Solution:
def maxScore(self, cardPoints: List[int], k: int) -> int:
myList = []
if len(cardPoints) == k:
return sum(cardPoints)
else:
while len(myList) < k:
if cardPoints[0] > cardPoints[-1]:
myList.append(cardPoints[0])
cardPoints.pop(0)
elif cardPoints[0] < cardPoints[-1]:
myList.append(cardPoints[-1])
cardPoints.pop(-1)
elif cardPoints[0] == cardPoints[-1]:
if cardPoints[1] > cardPoints[-2]:
myList.append(cardPoints[0])
cardPoints.pop(0)
elif cardPoints[1] < cardPoints[-2]:
myList.append(cardPoints[-1])
cardPoints.pop(-1)
else: 
myList.append(cardPoints[-1])
cardPoints.pop(-1)
return sum(myList)

正如你所看到的,这是一个非常混乱的方法,但它不起作用。它适用于一些测试用例,但它停止的是:

Input:

[11,49,100,20,86,29,72]
4

Output:

207

Expected:

232

我已经一步一步地解决了这个问题,我不明白为什么会有232。

据我所知,我们应该从列表中选择第一个或最后一个项目,基于哪个值更高。

在这种情况下,我们将首先比较1172

72放入新列表中,然后比较1129

29放入新列表中,然后比较1186

86放入新列表中,然后比较1120

20放入新的列表中,我们得到了72, 29, 86, 20的最终列表。

加起来,72 + 29 + 86 + 20 = 207,这就是我的代码得到的答案。

为什么代码期望232

有人能解释一下我在这里缺了什么吗?

正如评论中所指出的,您不应该对此使用贪婪的方法,否则您可能会选择错误的序列。例如,如果您的数组是[1,100,3,2]k=2,那么您的算法将生成5,尽管它必须是101

正确的方法是尝试cardPoints[-k]cardPoints[k - 1](包括两者(之间长度为k的每个数组子段,并选择和最大的一个子段。您只需要检查k + 1段,时间复杂度仅为O(k((见下文(。

def maxScore(self, cardPoints: List[int], k: int) -> int:
currentScore = sum(cardPoints[:k])
maxScore = currentScore
size = len(cardPoints)
for i in range(k):
currentScore += cardPoints[size - 1 - i]
currentScore -= cardPoints[k - 1 - i]
maxScore = max(maxScore, currentScore)

return maxScore 

我们从左线段的和开始,然后逐渐将其转换为右线段。在每一步中,我们都会确保更新最大分数。

我在LeetCode上运行了这个解决方案,它很好地被接受了。

最新更新