程式碼隨想錄演算法訓練營day27| 122.買賣股票的最佳時機II 55. 跳躍遊戲 45.跳躍遊戲II 1005.K次取反後最大化的陣列和

Tristan241001發表於2024-10-27

學習資料:https://programmercarl.com/0122.買賣股票的最佳時機II.html#演算法公開課

貪心PART2

學習記錄:
122.買賣股票的最佳時間2 (求最大利潤,貪心:把所有正數相加;後一天與當天的股票價格差值,若為正就加入利潤,若為負,則不加)

點選檢視程式碼
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 貪心法:計算隔天的價格漲跌值,若為正數就是最佳時機的組成之一
        result = 0
        for i in range(1, len(prices)):  # 從第二天開始,保證i-1存在
            add_p = max(prices[i]-prices[i-1], 0)  # 若漲價則結果加上該值,若跌就加0
            result += add_p
        return result
        

55.跳躍遊戲(引數:覆蓋範圍cover,當前位置i對應的可跳範圍i+nums[i],貪心:求最大覆蓋範圍,能到最後一個值,就是可跳躍的)

點選檢視程式碼
class Solution:
    def canJump(self, nums: List[int]) -> bool:
        # 貪心:儘量要大的覆蓋範圍,最終得最大覆蓋範圍
        if len(nums) == 1:  # 如果只有一個元素,那已經跳到最後一個位置了
            return True
        cover_index = 0     # 求可覆蓋範圍的最後位置的腳標
        for i in range(len(nums)):
            if i<=cover_index:  # 若最多跳2步,那可跳1步,跳2步,在覆蓋範圍內隨便跳
                # 若可跳範圍超過覆蓋範圍,就更新覆蓋範圍
                cover_index = max(cover_index, i+nums[i]) 
                # 覆蓋範圍腳標大於等於最後一個元素的腳標就滿足條件了 
                if cover_index >= len(nums)-1:
                    return True
        return False
        

45.跳躍遊戲2(比較難,當前可跳範圍終點為cur,當前位置i可跳範圍next=max(next, i+nums[i]),當到達可跳範圍終點卻還沒到陣列最後一位數時,則得繼續跳,若next包含陣列最後一個數,則剛剛跳完必到,就不用跳下一次了)

點選檢視程式碼
class Solution:
    def jump(self, nums: List[int]) -> int:
        # 貪心法:看下一次跳躍範圍,如果不能到終點,必然就還要再跳下一步
        cur = 0  # 當前位置
        next = 0 # 下一步最遠能跳的位置
        result = 0  # 最終需要跳躍的步數
        if len(nums)==1:  # 如果第一步就是最後一步,就根本不需要跳
            return 0
        for i in range(len(nums)):
            next = max(next, i+nums[i])  # 該步可跳範圍內,每個位置能繼續跳的範圍不同,只有當覆蓋範圍增大時,才更新最遠覆蓋位置
            if i == cur:   # 當索引走到當前位置
                if i != len(nums)-1:   
                    result += 1   # 跳下一步了
                    cur = next    # 當前位置更新
                    if cur >= len(nums)-1:  # 說明此時覆蓋位置包含了最後一個位置,ok
                        break
                else:
                    break   # 當前位置正好是最後位置,就不用跳了
        return result

        

1005.K次取反後最大化的陣列和(貪心:把絕對值最大的負數變成正數,可以讓和變大;再不濟就動絕對值最小的數,不管為正還是為負,影響都最小)

點選檢視程式碼
class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        # 貪心:把絕對值最大的負數取反,若還有操作次數,只能把最小的正數取反,讓陣列的和保持最大
        nums.sort(key=lambda x:abs(x), reverse=True)  # 先根據絕對值排序,從大到小
        for i in range(len(nums)):
            if nums[i]<0 and k>0:   # 如果該值為負,且還有操作次數
                nums[i] *= -1       # 取反
                k -= 1              # 操作次數減一
         # 如果所有負數都變成正數了,還有操作次數,就全部對絕對值最小的那個數進行取正負操作,如果次數是偶數,則結果不變,如果是奇數,則結果取反。
        if k%2 == 1:   
            nums[-1] *= -1
        return sum(nums)

        

PS:今天補週六的內容,今天天氣超好,開心心
吃大餐咯,心心念唸的部隊火鍋(我媽有能讓任何菜變香變辣的魔法),圓子湯,還有不停炫的水果,爽歪歪

相關文章