55-jump Game 跳躍遊戲

金字塔下的蜗牛發表於2024-05-11

問題描述

You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position.

Return true if you can reach the last index, or false otherwise

解釋:

給定一個數字nums,你被放在第一個位置上,nums中的每一個元素代表你處於該位置最多可以跳幾步。

如果能跳到最後一個位置,返回true;否則返回false

案例

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.\
解釋:
第一個位置跳1步道第二個位置,第二個位置跳3步到最後一個位置

基本思想-1

設nums的大小為size,構建長度為size的陣列dp。

  • dp[i] 表示的是nums[0~i-1] 有多少種方法可以跳至i位置,則dp[i] 的更新依賴於 nums[0~i-1], 具體如下:
    • 假設0<=j <=i-1, 如果 nums[j] + j >= i,那麼說明由j位置可以跳到i,此時 dp[i] = dp[j] ,因為可能存在多個滿足上述條件的j,所以 公式修改為 dp[i] = dp[j] + dp[i]

時間複雜度\(o(n^2)\)

程式碼實現如下

    def canJump(self, nums: List[int]) -> bool:
        size = len(nums)
        if size <=1 : return True
        dp = [0] * size
        dp[0] = 1 # dp[i] 跳到第i個位置的方法數目
        for i in range(1,size):
            for j in range(0,i):
                if (nums[j] > 0)  and (dp[j] > 0) and ((nums[j] + j ) >= i):
                    dp[i] = dp[i] + dp[j]
           
        return dp[size-1]>0

上述程式碼報錯,提示 Time Limit Exceeded ,測試用例明顯陣列太大了,時間複雜度太高了

最佳化

記錄0~i-1最多能跳到那個位置x,

對於位置i,只需要判斷i位置是否能到達 & i位置是否可以繼續跳。

當i<=x ,表示i位置可以跳到。知道進行到倒數第二個位置,此時 0~size-1的最大能跳躍位置是x,如果\(x >= size-1​\), 則表示可以跳到最終位置,否則表示不能跳到

程式碼

C++

    bool canJump(vector<int>& nums) {
        int size = nums.size();
        if (size<=1) return true;
        if (nums[0]<=0) return false;
        int maxLoc = nums[0];
        int maxLocIndex = 0;
        for(int i=1;i<(size-1);++i) {
            if (nums[i]<=0 || i > maxLoc) continue; // 如果i位置達不到 或者 i位置沒辦法跳躍
            if ((nums[i]+i) >= maxLoc) {
                maxLoc = nums[i] + i;
                maxLocIndex = i;
            }
        }
        return (size-1) <= maxLoc;
    }

相關文章