力扣:可獲得的最大點數 中等速度內存超快

題目描述
在這裏插入圖片描述
五個實例
在這裏插入圖片描述


在這裏插入圖片描述
提示
在這裏插入圖片描述
🔑解題思路

  • 思路1:最開始想到的是 dfs,從最開始的節點出發,要麼選左,要麼選右,選擇了一邊之後如果還能選,那再繼續上述過程,這不就是一棵樹,然後就按dfs寫的,但在用例較長的情況下超時了,只通過了 15/40 的樣例。思路1只是提供一種思考的思路,耗時過多,沒法通過本題。
  • 思路2:逆向思維,按題中意思取左取右得最大值,反過來就是求中間連續子數組得和最小,由於要取 k 張牌,所以反過來就是在中間找連續的長度爲 len(carPoints)-k 的子數組使其和最小,滑窗將移動 k 次,不斷更新滑窗能得到和的最小值,最後用輸入數組的和減去這個最小值就是結果。主要還是算清楚滑窗的左右邊界和題中已知量的關係,爲了配合理解,大家可以對照下面的 PPT 看一下,第一排各自代表 index,第二行代表對應位置的數值,用的是題中第一個範例。

SRC

class Solution:
    def maxScore(self, cardPoints: List[int], k: int) -> int:
        if len(cardPoints) == k:  # 如果取的次數等於長度,說明把所有牌都取走,直接返回總和
            return sum(cardPoints)
        # 逆向思維,按題中意思取左取右得最大值,反過來就是求中間連續子數組得和最小
        # 由於要取 k 張牌,所以反過來就是在中間找連續的長度爲 len(carPoints)-k 的子數組使其和最小,這以部分就是滑動窗口
        res_opposite = sum(cardPoints[:len(cardPoints) - k])  # 變量存儲滑窗的最小值,這裏先按初始位置賦初值
        current_sum = res_opposite  # current_sum記錄當前滑窗總和
        left_idx, right_idx = 0, len(cardPoints) - k - 1  # 設定滑窗邊界
        for _ in range(k):  # 滑窗將移動 k 次
            left_idx += 1  # 更新滑窗左右邊界
            right_idx += 1
            # 計算新位置滑窗內值的總和,減去滑窗原來的左邊界,加上滑窗新的右邊界
            current_sum = current_sum - cardPoints[left_idx - 1] + cardPoints[right_idx]  
            res_opposite = min(res_opposite, current_sum)  # 更新最小的滑窗範圍內的和
        return sum(cardPoints) - res_opposite
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章