遊戲模擬 Jump Game 青蛙過河 Leetcode_#55

更新於 發佈於 閱讀時間約 7 分鐘

題目敘述

題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以跳躍的最大長度

一開始從最左邊的格子點出發開始跳,請問可以成功抵達終點,也就是最右邊的格子點嗎?

如果可以,返回 True。

如果不行,返回False。


題目的原文敘述


測試範例

Example 1:

Input: nums = [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.

0 -> 1 - > 4
先從零跳一步到1
再從13步,可以抵達終點​,也就是第四個格子點。

Example 2:

Input: nums = [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.
無​解,跳不過去。

約束條件

Constraints:

  • 1 <= nums.length <= 10^4

輸入陣列的長度介於1 ~ 10^4 。

  • 0 <= nums[i] <= 10^5

每個格子點最小可以跳0格,相當於留在原地代表題目可能會給陷阱格子

最大可以跳10^5個格子。


演算法 第一知覺的想法

第一直覺想到就是依照遊戲規則去模擬,盡量往右邊跳,看看能不能從起點0開始跳到終點?

當然是可以的,但是仔細留意一下,nums[i]最大可以有10^5,代表每個格子點可能的選擇(也就是分枝)可以有十萬條路徑,顯然用直接進行模擬會存在執行速度太慢或者time-out超過時間限制的風險,因為是指數級別的枚舉所有跳躍路徑


這題其實用DFS模擬,或者BFS模擬跳躍,還是勉強可以通過平台的測試。


但是,後面我們會介紹一個更好的演算法,採用貪心策略Greedy strategy的演算法來提升速度

程式法 DFS模擬跳躍

class Solution:
def canJump(self, nums: List[int]) -> bool:

destination = len(nums)-1

if destination == 0:
return True

seen = set([0])

def dfs(i):

if i >= destination:
return True

for jump in range(1, nums[i]+1) :
if (i + jump) not in seen:
seen.add( i + jump )
if i + jump >= destination or dfs( i + jump):
return True

return False

# ===========================
return dfs( i = 0)

程式碼 BFS模擬跳躍

class Solution:
def canJump(self, nums: List[int]) -> bool:

destination = len(nums)-1

if destination == 0:
return True

bfs_q = deque([0])
seen = set([0])

while bfs_q:

cur = bfs_q.popleft()

for jump in reversed(range(1, nums[cur]+1)):

if cur + jump >= destination:
return True

if cur+jump not in seen:
bfs_q.append( cur+jump )
seen.add( cur+jump )

return False

演算法 Greedy 策略 盡量去延伸我能抵達的地方

其實題目真正問的關鍵在於"能不能夠"抵達終點?

題目並沒有去要求我們列出跳躍的路徑(也就是過程)。

題目只關心結果,能不能抵達終點?


換句話說,假如我們經由跳躍能夠碰觸的範圍,盡量去往右邊延伸,可以覆蓋到終點,那麼一定有解,可以從起點開始跳躍,抵達終點。

如果不行,則代表半路上就停下來了,已經盡力跳了,但是就是過不去,無解,返回False。


程式碼 Greedy 策略 盡量去延伸我能抵達的地方

class Solution:
def canJump(self, nums: List[int]) -> bool:

# 能夠抵達的範圍
max_reach = nums[0]

for i, jump in enumerate(nums):

# 已經盡力跳了,但是到不了 index i,
# 半路上就被迫停下來了,無解。
if max_reach < i:
return False

# 盡量去往右邊延伸經由跳躍能夠碰觸的範圍,
max_reach = max(max_reach, i + jump)

# 假如跳耀的範圍能覆蓋終點,那麼一定有解
return max_reach >= ( len(nums)-1 )

複雜度分析 Greedy 策略 盡量去延伸我能抵達的地方

令n=輸入陣列nums的長度

時間複雜度:

從左邊到右邊逐一檢查每個格子點,盡量去延伸跳躍能覆蓋的範圍,總共所需時間為O(n)。


空間複雜度:

用到的都是固定尺寸的臨時變數,總共所需空間為O(1)。


關鍵知識點

題目並沒有去要求我們列出跳躍的路徑(也就是過程)。

題目只關心結果,能不能抵達終點?

換句話說,假如我們經由跳躍能夠碰觸的範圍,盡量去往右邊延伸,可以覆蓋到終點,那麼一定有解,可以從起點開始跳躍,抵達終點。

如果不行,則代表半路上就停下來了,已經盡力跳了,但是就是過不去,無解,返回False。


Reference:

[1] Jump Game_Python solution sharing

avatar-img
91會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
題目敘述 題目會給我們一個房間陣列rooms,每個房間裡面擁有數量不等,可以打開其他房間的鑰匙。 每一道房間門預設都是鎖住的,只有0號房間的門一開始是打開的。 請問,從0號房間開始拿鑰匙,最終能不能打開所有房間的門? 題目的原文敘述 測試範例
題目敘述 題目會給我們一顆二元樹的根結點,請我們列出每一層最右邊的節點值,以陣列的形式返回答案。 題目的原文敘述 測試範例 Example 1: Input: root = [1,2,3,null,5,null,4] Output: [1,3,4] 每一層最右邊的節點值分別是1, 3,
題目敘述 題目會給定我們一個字串s,和一組字庫wordDict。 問我們能不能透過字串串接的方式,從字庫裡面的字拼成原本的字串s? 可以的話,返回True。 無解的話,返回False。 註: 題目還允許重複使用字庫裡面的字去串接。
題目敘述 題目會給定一個指定高度和寬的方格版,還有一顆小球的起始位置,和最大移動步數。 小球每一步可以選擇向上、下、左、右移動一格,請問小球能走到方格版界外的路徑方法數總共有幾種? 方法數可能很大,題目要求,最後回傳答案時,先對10^9+7做除法取餘數再回傳。 題目的原文敘述 約束條件
題目敘述 題目給定我們一顆二元樹的根節點,要求我們計算出從根節點到葉子節點的偽回文路徑路徑有幾條? 偽回文路徑路徑 的定義: 路徑經過重新排列之後,可以形成回文Palindrome,也就是頭尾鏡像對稱。 ​ 例如: 1 -> 3 -> 3 重新排列之後,可以形成 3 -> 1 -> 3
題目敘述 題目會給定一個字串陣列arr最為輸入,我們可以任意選擇一組不包含重複字元的陣列子序列,將字串進行串接,成為字串s,請問字串s的最大長度是多少? 例如: arr=["dog","cow","cat"] 我們可以選擇"dog", "cat"進行串接,得到的字串s="dogcat",s的
題目敘述 題目會給我們一個房間陣列rooms,每個房間裡面擁有數量不等,可以打開其他房間的鑰匙。 每一道房間門預設都是鎖住的,只有0號房間的門一開始是打開的。 請問,從0號房間開始拿鑰匙,最終能不能打開所有房間的門? 題目的原文敘述 測試範例
題目敘述 題目會給我們一顆二元樹的根結點,請我們列出每一層最右邊的節點值,以陣列的形式返回答案。 題目的原文敘述 測試範例 Example 1: Input: root = [1,2,3,null,5,null,4] Output: [1,3,4] 每一層最右邊的節點值分別是1, 3,
題目敘述 題目會給定我們一個字串s,和一組字庫wordDict。 問我們能不能透過字串串接的方式,從字庫裡面的字拼成原本的字串s? 可以的話,返回True。 無解的話,返回False。 註: 題目還允許重複使用字庫裡面的字去串接。
題目敘述 題目會給定一個指定高度和寬的方格版,還有一顆小球的起始位置,和最大移動步數。 小球每一步可以選擇向上、下、左、右移動一格,請問小球能走到方格版界外的路徑方法數總共有幾種? 方法數可能很大,題目要求,最後回傳答案時,先對10^9+7做除法取餘數再回傳。 題目的原文敘述 約束條件
題目敘述 題目給定我們一顆二元樹的根節點,要求我們計算出從根節點到葉子節點的偽回文路徑路徑有幾條? 偽回文路徑路徑 的定義: 路徑經過重新排列之後,可以形成回文Palindrome,也就是頭尾鏡像對稱。 ​ 例如: 1 -> 3 -> 3 重新排列之後,可以形成 3 -> 1 -> 3
題目敘述 題目會給定一個字串陣列arr最為輸入,我們可以任意選擇一組不包含重複字元的陣列子序列,將字串進行串接,成為字串s,請問字串s的最大長度是多少? 例如: arr=["dog","cow","cat"] 我們可以選擇"dog", "cat"進行串接,得到的字串s="dogcat",s的
你可能也想看
Google News 追蹤
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
分享一個猜數字的遊戲題目,給予提示讓玩家找出正確的四位數密碼。
Thumbnail
給定一個9x9的輸入陣列代表數獨題目已經 部分作答 的狀態, 請驗證已經作答的部分是否為合法的Sudoku的輸入。 註: 合法的Sudoku輸入必須滿足這些規則 1~9每一直排恰好出現一次。 1~9每一橫排恰好出現一次。 1~9在3x3的小方陣裏恰好出現一次。
Thumbnail
 如果你有緣看到這篇文字,且興緻勃勃地從第一個字看到最後一個字,代表你已經或即將要跨入這條「文字變現」的賽道了。眼下我們所處的這條賽道,係由「方格子文字創作平台」無償提供。賽道的終點目標並没有被設立,想怎麼跑,想跑至哪裡,係由參賽者自行決定。當然啦!賽道並不只有方格子這一條;而你的對手是跟你一樣
Thumbnail
任天堂2月底時對知名的Switch模擬器Yuzu出手🥊,在美國向Yuzu的開發者提起訴訟,指控其促使巨大規模的盜版行為。 但這場法律戰以迅雷不及掩耳的速度結束了──Yuzu一方直接繳械投降,舉白旗認輸。 然而,遊戲模擬器會不會侵害著作權?Yuzu一方又到底做了什麼惹到任天堂? 讓我們一起來看看~
Thumbnail
題目敘述 題目會給我們一個輸入陣列arr,起始點固定在索引為0的位置, 終點固定在索引為n-1的位置。 假設當下所在的索引位置為i,那麼每次移動的時候,可以跳到i-1,i+1,或者其他和我有相同元素值的位置arr[j], where arr[j] = arr[i]。 例如: 假設當下在i=3
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以左右位移的固定長度。 例如,假設 nums[i] = 3,那麼下一步可以移動到nums[i-3] 或 nums[i+3]這兩個格子點。 題目​會給定一個起始點start索引位置,請問我們能不能走到內部數值為0的格子點?
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以跳躍的最大長度。 題目保證始從最左邊的格子點出發開始跳,一定可以成功抵達終點,請問最少跳躍次數是說少? 題目的原文敘述 測試範例 Example 1: Input: nums = [2,3,1,1,4] Outp
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
分享一個猜數字的遊戲題目,給予提示讓玩家找出正確的四位數密碼。
Thumbnail
給定一個9x9的輸入陣列代表數獨題目已經 部分作答 的狀態, 請驗證已經作答的部分是否為合法的Sudoku的輸入。 註: 合法的Sudoku輸入必須滿足這些規則 1~9每一直排恰好出現一次。 1~9每一橫排恰好出現一次。 1~9在3x3的小方陣裏恰好出現一次。
Thumbnail
 如果你有緣看到這篇文字,且興緻勃勃地從第一個字看到最後一個字,代表你已經或即將要跨入這條「文字變現」的賽道了。眼下我們所處的這條賽道,係由「方格子文字創作平台」無償提供。賽道的終點目標並没有被設立,想怎麼跑,想跑至哪裡,係由參賽者自行決定。當然啦!賽道並不只有方格子這一條;而你的對手是跟你一樣
Thumbnail
任天堂2月底時對知名的Switch模擬器Yuzu出手🥊,在美國向Yuzu的開發者提起訴訟,指控其促使巨大規模的盜版行為。 但這場法律戰以迅雷不及掩耳的速度結束了──Yuzu一方直接繳械投降,舉白旗認輸。 然而,遊戲模擬器會不會侵害著作權?Yuzu一方又到底做了什麼惹到任天堂? 讓我們一起來看看~
Thumbnail
題目敘述 題目會給我們一個輸入陣列arr,起始點固定在索引為0的位置, 終點固定在索引為n-1的位置。 假設當下所在的索引位置為i,那麼每次移動的時候,可以跳到i-1,i+1,或者其他和我有相同元素值的位置arr[j], where arr[j] = arr[i]。 例如: 假設當下在i=3
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以左右位移的固定長度。 例如,假設 nums[i] = 3,那麼下一步可以移動到nums[i-3] 或 nums[i+3]這兩個格子點。 題目​會給定一個起始點start索引位置,請問我們能不能走到內部數值為0的格子點?
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,每個元素值代表那個格子點可以跳躍的最大長度。 題目保證始從最左邊的格子點出發開始跳,一定可以成功抵達終點,請問最少跳躍次數是說少? 題目的原文敘述 測試範例 Example 1: Input: nums = [2,3,1,1,4] Outp