LeetCode 跳跃游戏系列

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没有显式地用到队列,需要学习。

猜你喜欢

转载自www.cnblogs.com/hlk09/p/9746931.html