【算法】leetcode 45. 跳躍遊戲 II(貪心作祟)(順藤摸瓜與順瓜摸藤)

問題來源

45. 跳躍遊戲 II
給定一個非負整數數組,你最初位於數組的第一個位置。

數組中的每個元素代表你在該位置可以跳躍的最大長度。

你的目標是使用最少的跳躍次數到達數組的最後一個位置。

示例:

輸入: [2,3,1,1,4]
輸出: 2
解釋: 跳到最後一個位置的最小跳躍數是 2。
     從下標爲 0 跳到下標爲 1 的位置,跳 1 步,然後跳 3 步到達數組的最後一個位置。
說明:

假設你總是可以到達數組的最後一個位置。

大佬解析


代碼


"""
需求:
    假設你總是可以到達數組的最後一個位置, 你的目標是使用最少的跳躍次數到達數組的最後一個位置。
    
思想:
    1.動態規劃:計算每個位置可達的下一位置的最少步數
    2.回溯+備忘錄
    3.貪心策略:記錄每個位置能到達的最遠距離,設置邊界,標記步數
"""


class Solution:

    def jump(self, nums) -> int:
        # 1.貪心策略:記錄每個位置能到達的最遠距離,設置邊界,標記步數
        """
        題目說明:假設你總是可以到達數組的最後一個位置。
        即一定存在一條路線能夠到達最後一個位置,而不是說中間沒有 0 ,只是存在可以越過 0 的路線

        貪心算法:找能跳的最遠的
        使用 k 記錄目前能夠跳到的最高位置
        使用 end 記錄這次跳躍的邊界,到達邊界就跳躍次數 + 1

        過程解析:
        最開始遍歷 i = 0, end = 0,因此 step 會進行 step ++,我們可以認爲,這是開始起跳,因爲必定會落下,因此跳躍次數 + 1
        而 nums[0] 這個數限制了你只能在落腳在某個範圍內,假如 nums[0] = 4,那麼你只能選擇落腳在 [1, 4] 位置,而如果到了邊界,那麼肯定是一次新的起跳,因此次數需要再 + 1

        從 0 位置開始起跳,你落腳的必定是 [1, 4] 位置中能夠跳得更遠的,因爲根據貪心思想,這樣做能夠儘可能的減少跳躍次數,因爲更加接近最後一個位置
        而在這個過程遍歷 [1, 4] 過程中一直記錄着最遠位置 k,而你落地在 [1, 4] 之間,落地的那個點也就是 [1, 4] 之間最能夠跳得遠的那個位置,因此當到達邊界的時候,將 end 更新爲 k

        注意:[1, 4] 跳得最遠的位置必定不會在 [1, 4] ,因爲如果在 [1, 4] ,那麼表示根本就出不去 [1, 4] 這個圈
        當然不會是 [4,1,1,1,0,1,2] 這種的,因爲如果是這種的,壓根過不去這個 0,因此必定第一次起跳必定能夠跳出 [1, 4] 這個範圍,比如 [4,1,1,1,1,1,0]

        """

        max_pos = 0
        end = 0
        step = 0

        for i in range(len(nums) - 1):
            max_pos = max(max_pos, i + nums[i]) # 更新最遠距離

            if i == end:  # 體現貪心策略,在邊界處更新
                end = max_pos
                step += 1

        return step

    def jump1(self, nums) -> int:
        # 1.動態規劃:計算每個位置可達的下一位置的最少步數
        size = len(nums)
        if not size:
            return 0

        longest_jump = [float('inf')] * size
        longest_jump[0] = 0
        for i, v in enumerate(nums):
            for j in range(i + 1, min((i + nums[i]) + 1, size)):
                longest_jump[j] = min(longest_jump[j], longest_jump[i] + 1)
        return longest_jump[-1]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章