1. 程式人生 > >LeetCode 跳躍遊戲系列

LeetCode 跳躍遊戲系列

i+1 clas 條件 最小 false 顯式 class [] 動態規劃

55. 跳躍遊戲

給定一個非負整數數組,你最初位於數組的第一個位置。數組中的每個元素代表你在該位置可以跳躍的最大長度。判斷你是否能夠到達最後一個位置。

示例 1:

輸入: [2,3,1,1,4]
輸出: true
解釋: 從位置 0 到 1 跳 1 步, 然後跳 3 步到達最後一個位置。

示例 2:

輸入: [3,2,1,0,4]
輸出: false
解釋: 無論怎樣,你總會到達索引為 3 的位置。但該位置的最大跳躍長度是 0 , 所以你永遠不可能到達最後一個位置。

從直覺上看,因為問題只是問能不能跳到最後一個位置,所以總共能跳得越遠越好。記longest為能到達的最遠位置,那麽有longest = max(longest, i + nums[i])。如果從起點跳longest步還不能到達當前位置,那麽也到不了最後一個位置。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int longest = 0;
        for(int i = 0; i < nums.size(); i++) {
            if(longest < i) {
                return false;
            }
            longest = max(longest, i + nums[i]);
        }
        return longest >= nums.size() - 1
; } };

45. 跳躍遊戲 II

給定一個非負整數數組,你最初位於數組的第一個位置。數組中的每個元素代表你在該位置可以跳躍的最大長度。你的目標是使用最少的跳躍次數到達數組的最後一個位置。

示例:

輸入: [2,3,1,1,4]
輸出: 2
解釋: 跳到最後一個位置的最小跳躍數是 2。
     從下標為 0 跳到下標為 1 的位置,跳 1 步,然後跳 3 步到達數組的最後一個位置。

說明:

假設你總是可以到達數組的最後一個位置。

由於問題是求最小步數,第一反應是利用動態規劃求解。設數組longest和dp,其中longest[i]表示從i出發能到的最遠地方,dp[i]表示到達i所需要的最小步數。那麽dp[i] = min(dp[j] + 1, dp[i]),其中dp初始化為INT_MAX,dp[0] = 0,轉移條件為j < i && dp[j] != INT_MAX && longest[j] >= i。

class Solution {
public:
    int jump(vector<int>& nums) {
        int tmp = 0;
        vector<int> dp(nums.size(), INT_MAX);
        vector<int> longest(nums.size(), 0);
        dp[0] = 0;
        for(int i = 0; i < nums.size(); i++) {
            longest[i] = tmp = max(tmp, nums[i] + i);
        }
        for(int i = 1; i < nums.size(); i++) {
            for(int j = 0; j < i; j++) {
                if(dp[j] != INT_MAX && longest[j] >= i) {
                    dp[i] = min(dp[i], dp[j] + 1);
                }
            }
        }
        return dp[nums.size() - 1];
    }
};

但是這樣子做會超時。因為問題求的是最小步數,可以考慮BFS的做法。把每一個索引看作是節點,可以每一層來看。先上代碼:

int jump(int A[], int n) {
     if(n<2)return 0;
     int level=0,currentMax=0,i=0,nextMax=0;

     while(currentMax-i+1>0){        //nodes count of current level>0
         level++;
         for(;i<=currentMax;i++){    //traverse current level , and update the max reach of next level
            nextMax=max(nextMax,A[i]+i);
            if(nextMax>=n-1)return level;   // if last element is in level+1,  then the min jump=level 
         }
         currentMax=nextMax;
     }
     return 0;
 }

level表示該層節點的層數,也是表示到達下一層的步數。currentMax表示當前層中,最遠能到達的節點索引,nextMax用來表示下一層最遠能到達的節點索引。

這種bfs沒有顯式地用到隊列,需要學習。

LeetCode 跳躍遊戲系列