問題來源
45. 跳躍遊戲 II
給定一個非負整數數組,你最初位於數組的第一個位置。
數組中的每個元素代表你在該位置可以跳躍的最大長度。
你的目標是使用最少的跳躍次數到達數組的最後一個位置。
示例:
輸入: [2,3,1,1,4]
輸出: 2
解釋: 跳到最後一個位置的最小跳躍數是 2。
從下標爲 0 跳到下標爲 1 的位置,跳 1 步,然後跳 3 步到達數組的最後一個位置。
說明:
假設你總是可以到達數組的最後一個位置。
大佬解析
代碼
"""
需求:
假設你總是可以到達數組的最後一個位置, 你的目標是使用最少的跳躍次數到達數組的最後一個位置。
思想:
1.動態規劃:計算每個位置可達的下一位置的最少步數
2.回溯+備忘錄
3.貪心策略:記錄每個位置能到達的最遠距離,設置邊界,標記步數
"""
class Solution:
def jump(self, nums) -> int:
"""
題目說明:假設你總是可以到達數組的最後一個位置。
即一定存在一條路線能夠到達最後一個位置,而不是說中間沒有 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:
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]