1.題目描述 55. 跳躍遊戲
給定一個非負整數數組,你最初位於數組的第一個位置。
數組中的每個元素代表你在該位置可以跳躍的最大長度。
判斷你是否能夠到達最後一個位置。
示例 1:
輸入: [2,3,1,1,4]
輸出: true
解釋: 我們可以先跳 1 步,從位置 0 到達 位置 1, 然後再從位置 1 跳 3 步到達最後一個位置。
示例 2:
輸入: [3,2,1,0,4]
輸出: false
解釋: 無論怎樣,你總會到達索引爲 3 的位置。但該位置的最大跳躍長度是 0 , 所以你永遠不可能到達最後一個位置。
2.思路分析
2.1 從最後一個位置向前反推,若有位置大於等於二者位置差,則爲可到達點,根據可到達點繼續反推,知道找到idx爲0的位置返回true,或者可到達數組爲空代表無法到達, 這個思路比較樸素,基本上是遞歸的思想。加入已經遍歷位置優化後,效率有一定提升,但是加上遞歸寫法,堆棧調用等增加了時間,最後幾個用例沒過。後來參照官方題解,優化了我的遞歸代碼,加入了最長距離的優化,發現還是沒有cover所有用例時間,所以主要還是遞歸寫法問題
2.2 自己沒有思路了,參照了官方題解,不過官方題解說的有點不清晰,自己寫了一下代碼。具體思路就是不斷計算從開始位置的最遠的到達點,從前向後遍歷,在當前最遠可到達點之前遍歷的時候可以更新最遠可到達點,若遍歷到當前最大可到達點,依然還是沒有到末尾,提前返回false
3.debug過程
1.自己的思路沒有處理只有一個元素的情況
2.官方題解自己實現第一個版本,沒有提前return 53ms,慢一點,提前return後 32ms
4.成績
執行用時 :32 ms, 在所有 Python 提交中擊敗了68.61%的用戶
內存消耗 :13.4 MB, 在所有 Python 提交中擊敗了11.11%的用戶
5.ac代碼(python)
class Solution(object):
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
思路: 從最後一個位置向前反推,若有位置大於等於二者位置差,則爲可到達點,根據可到達點繼續反推,知道找到idx爲0的位置返回true,或者可到達數組爲空代表無法到達
"""
if len(nums) == 1:
return True
# has_cal_idxs = [0 for _ in range(len(nums))]
# def canjump(nums, end_idx):
# for i in range(end_idx-1, -1, -1):
# if nums[i] >= end_idx - i:
# if i == 0:
# return True
# if has_cal_idxs[i]:
# continue
# result = canjump(nums, i)
# if result:
# return True
# has_cal_idxs[i] = 1
# return False
# return canjump(nums, len(nums)-1)
max_reach_idx = nums[0]
for idx, num in enumerate(nums):
if idx <= max_reach_idx:
if idx + num >= max_reach_idx:
max_reach_idx = idx + num
if max_reach_idx > len(nums) - 2:
return True
else:
return False