跳躍遊戲精細化

宇宙之无限大發表於2024-04-20

跳躍遊戲

​ 給定一個陣列,每個元素代表跳躍的距離,判斷是否能從起點出發,跳到陣列的末尾。

​ 例如:給定一陣列[3,7,8,1,5],從起點出發,可以跳躍3步,跳到位置3,然後跳1步,跳到位置4,跳4步到達末尾

思路分析

  • 定義一個變數,用來初始化當前能到達最遠位置
  • 遍歷陣列,獲取當前位置索引及值,這裡使用到enumerate函式,用來實現能夠同時獲取到當前位置及值。
  • 若當前位置超出了能夠到達的最遠位置,則無法繼續跳躍
  • 使用 max數更新 最遠距離,確保它總是表示當前能到達的最遠位置。
  • 遍歷完成後,檢查 max_distance 是否至少為陣列長度減一,即是否能到達最後一個位置

enumerate簡述

​ Python內建的一個函式,它用於將一個可遍歷的資料物件(如列表、元組或字串)組合為一個索引序列,同時列出資料和資料下標,一般用在for迴圈當中。enumerate返回的是一個列舉物件,它包含元組,每個元組包含兩個元素,一個是索引值,一個是原始資料值。

舉例:

for index, value in enumerate(['a', 'b', 'c']):  
    print(f"Index: {index}, Value: {value}")

輸出結果:

Index: 0, Value: a  
Index: 1, Value: b  
Index: 2, Value: c

貪心演算法簡述

​ 貪心演算法是在每一步選擇中都採取在當前狀態下最好或最優(即最有利)的選擇,從而希望導致結果是全域性最好或最優的演算法。是從問題的某一個初始解出發逐步逼近給定的目標,以儘可能快地求得更好的解。並且希望透過所做的區域性最優選擇來導致最終的全域性最優解時,這樣的演算法就被稱為貪心演算法

​ 在canJump函式中,貪心策略體現在每一步都更新max_distance為當前位置能夠到達的最遠距離。這意味著在每一步,演算法都在儘可能地擴大能夠到達的範圍。

程式碼實現

def Jumping_Game(nums):
    max_distance = 0  # 記錄當前能夠到達的最遠位置
    for i, jump in enumerate(nums):  # 遍歷陣列,獲取當前位置的索引和跳躍長度
        if i > max_distance:  # 如果當前位置超出最遠能夠到達的位置,則無法繼續跳躍
            return False
        if i + jump >= len(nums) - 1:  # 如果能夠到達或超過最後一個位置,則返回True
            return True
        max_distance = max(max_distance, i + jump)  # 更新最遠能夠到達的位置

    return False  # 遍歷完陣列後仍未到達最後一個位置,返回False
if __name__ == '__main__':
    list_nums = [3, 3, 1, 1, 4]
    print(Jumping_Game(list_nums))  
    print('-' * 31)

    list_nums2 = [3, 2, 1, 0, 4]
    print(Jumping_Game(list_nums2)) 

測試用例詳述

測試用例一:list_nums = [3, 3, 1, 1, 4]

  • 從位置0開始,數值是3,意味著可以跳到位置0、1、2、3。

  • 一旦到達位置 1,發現從這個位置也可以跳躍的最大步數是 3,這意味著可以直接跳到位置 4(因為 1 + 3 >= 4)。在這種情況下,我們不需要遍歷位置 2 或位置 3,已經找到了一條從位置 0 到位置 4 的路徑。)。

    圖例(表格方式,紅色為跳躍數):
    image

測試用例二:list_nums2 = [3, 2, 1, 0, 4]

  • 同樣從位置0開始,數值是3,我們可以跳到位置0、1、2、3。

    更新max_distance為3。

  • 在位置1,數值是2,我們可以跳到位置1、2、3。此時max_distance仍然是3。

  • 在位置2,數值是1,我們只能跳到位置2或3。此時max_distance仍然是3。

  • 在位置3,數值是0,這意味著我們無法從這裡跳到更遠的位置。此時,i(當前位置)已經大於max_distance(最遠能夠到達的位置),所以函式返回False

圖例(表格方式,紅色為跳躍數):

總結

​ 關鍵在於每一步都儘可能地更新max_distance,從而確保我們不會錯過任何可能到達陣列的末尾路徑。

​ 時間複雜度:O(n),程式碼遍歷了陣列nums一次,沒有巢狀迴圈或其他會增加時間複雜度的操作。因此,時間複雜度是O(n),其中n是陣列nums的長度。

​ 空間複雜度:O(1),程式碼中只使用了幾個變數(如max_distance和i,jump)來追蹤當前能夠到達的最遠位置,當前下標,當前位置的值。這些變數不隨陣列nums的大小變化而增加,因此空間複雜度是O(1)。

相關文章