Leetcode (45) Jump Game II

  • 题目:

    Given an array of non-negative integers, you are initially positioned at the first index of the array.

    Each element in the array represents your maximum jump length at that position.

    Your goal is to reach the last index in the minimum number of jumps.

    For example:
    Given array A = [2,3,1,1,4]

    The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

  • 题意:这相当于一个跳棋的游戏,给定一个序列,表示某个位置能跳多远,求解从开始至少跳多少步到达终点。

  • 求解思路一:构图,序列中每个位置相当于一个点,而从该点能够跳到的位置,相当于有边相连,于是至少跳多少步相当于最短路问题。

    • 此时算法复杂度约为 O(n2) ,但这是一个比较松的上界,因为基本只有很特殊的情况才能到达,如[3,2,1,1,1],即终点前面的点都需要遍历的情况。
class Solution {
public:
    int jump(vector<int>& nums) {
        int size=nums.size();
        if (size == 1) return 0;
        bool vis[size];
        memset(vis,0,sizeof(vis));

        typedef pair<int,int> pii;
        queue que;
        vis[0]=true;
        que.push(make_pair(0,0));
        while (!que.empty())
        {
            pii p=que.front();
            que.pop();
            int num=nums[p.first];
            if (p.first+num>=size-1) return p.second+1;
            for (int i=num;i>=1;i--)
            {
                if (!vis[p.first+i])
                {
                    que.push(make_pair(p.first+i,p.second+1));
                    vis[p.first+i] = true;
                }
                else break;
            }
        }
        return 0;
    }
};
  • 求解思路二:宽搜的过程中实际上有一些是不必要走的步骤,如[3,6,3,2,1,1,1,…],则实际上第二步应该直接走6就好,因为走3都不如走6走得远,但是宽搜都会搜索到,并从那一步开始再搜索下一步。
  • 优化:注意到宽搜搜索到的任意一步都会从该步开始继续搜索,但是其实会发现没有这种必要,即从第一步3开始的时候,搜索下一步,[6,3,2]就可以变成[3,1,1],即3步之内,还能走多远,然后直接去到第一个1的时候直接取1即可。
  • 这就是贪心的思想,对下一步最远能走到哪里进行贪心,注意到数组下标总在前进,因此算法复杂度为O(n)
class Solution {
public:
    int jump(vector<int>& nums) {
        int size = nums.size();
        if (size == 1) return 0;
        int step = nums[0], ans = 1, i=0, next=-1;
        while (i < size)
        {
            if (i+step>=size-1) return ans;
            while (step > 0)
            {
                i++;
                step--;
                if (next==-1 || nums[i]+i>nums[next]+next)
                {
                    next=i;
                }
            }
            step = nums[next]-(i-next);
            next = -1;
            ans++;
        }
        return 0;
    }
};

你可能感兴趣的:(leetcode)