1423. 可獲得的最大點數
阿新 • • 發佈:2021-02-07
技術標籤:LeetCodepythonleetcode子陣列
難度中等
幾張卡牌排成一行,每張卡牌都有一個對應的點數。點數由整數陣列cardPoints
給出。每次行動,你可以從行的開頭或者末尾拿一張卡牌,最終你必須正好拿k
張卡牌。你的點數就是你拿到手中的所有卡牌的點數之和。
給你一個整數陣列cardPoints
和整數k
,請你返回可以獲得的最大點數。
示例 1:
輸入:cardPoints = [1,2,3,4,5,6,1], k = 3
輸出:12
解釋:第一次行動,不管拿哪張牌,你的點數總是 1 。但是,先拿最右邊的卡牌將會最大化你的可獲得點數。最優策略是拿右邊的三張牌,最終點數為 1 + 6 + 5 = 12 。示例 2:
輸入:cardPoints = [2,2,2], k = 2
輸出:4
解釋:無論你拿起哪兩張卡牌,可獲得的點數總是 4 。示例 3:
輸入:cardPoints = [9,7,7,9,7,7,9], k = 7
輸出:55
解釋:你必須拿起所有卡牌,可以獲得的點數為所有卡牌的點數之和。
第一版程式碼(先取最後的K個數作為最初的結果, 然後每次向後移動一位, 同時從最前面取一個數字, 依次進行, 直到取的是最前面得K個數字, 其中最大的陣列和就是結果)
class Solution: def maxScore(self, cardPoints: List[int], k: int) -> int: res = sum(cardPoints[-k:]) for i in range(1, k + 1): if i == k: li = cardPoints[:i] else: li = cardPoints[:i] + cardPoints[-(k-i):] tem = sum(li) if tem > res: res = tem return res
結果直接超出了時間限制, 因為每次都在求K個元素的和, 比較耗時
第二版程式碼(可以簡化為取陣列最後的K個數字,和取資料最前的K個數字組成新的陣列, 從中選取最大的K的子串,這次每次移動的時候就是減一個數字, 加一個數字, 不用每次都求和)
class Solution: def maxScore(self, cardPoints: List[int], k: int) -> int: li = cardPoints[-k:] + cardPoints[:k] res = temp = sum(li[:k]) left, right = 1, k while right < 2*k: temp = temp - li[left - 1] + li[right] if temp > res: res = temp right += 1 left += 1 return res
結果還不錯
第三版程式碼(我們再考慮一下特殊情況, 就是當陣列的長度就是K的時候, 我們直接求和即可)
class Solution:
def maxScore(self, cardPoints: List[int], k: int) -> int:
if k == len(cardPoints):
return sum(cardPoints)
li = cardPoints[-k:] + cardPoints[:k]
res = temp = sum(li[:k])
left, right = 1, k
while right < 2 * k:
temp = temp - li[left - 1] + li[right]
if temp > res:
res = temp
right += 1
left += 1
return res