LeetCode 题解 —— 1654. 到家的最少跳跃次数

题目相关

题目链接

LeetCode 中国,https://leetcode-cn.com/problems/minimum-jumps-to-reach-home/。

Problem Statement

有一只跳蚤的家在数轴上的位置 x 处。请你帮助它从位置 0 出发,到达它的家。

跳蚤跳跃的规则如下:

    它可以 往前 跳恰好 a 个位置(即往右跳)。
    它可以 往后 跳恰好 b 个位置(即往左跳)。
    它不能 连续 往后跳 2 次。
    它不能跳到任何 forbidden 数组中的位置。

跳蚤可以往前跳 超过 它的家的位置,但是它 不能跳到负整数 的位置。

给你一个整数数组 forbidden ,其中 forbidden[i] 是跳蚤不能跳到的位置,同时给你整数 a, b 和 x ,请你返回跳蚤到家的最少跳跃次数。如果没有恰好到达 x 的可行方案,请你返回 -1 。

Samples 1

输入:forbidden = [14,4,18,1,15], a = 3, b = 15, x = 9
输出:3
解释:往前跳 3 次(0 -> 3 -> 6 -> 9),跳蚤就到家了。

Samples 2

输入:forbidden = [8,3,16,6,12,20], a = 15, b = 13, x = 11
输出:-1

Samples 3

输入:forbidden = [1,6,2,14,5,17,4], a = 16, b = 9, x = 7
输出:2
解释:往前跳一次(0 -> 16),然后往回跳一次(16 -> 7),跳蚤就到家了。

数据范围

  • 1 <= forbidden.length <= 1000
  • 1 <= a, b, forbidden[i] <= 2000
  • 0 <= x <= 2000
  • forbidden 中所有位置互不相同。
  • 位置 x 不在 forbidden 中。

题解报告

题目分析

LeetCode 官方将本题难度定为中等。读完题目,本题求最短路径,哪就可以使用 BFS 了。

难点

难点一

和标准 BFS 相比,本题有一个限制,那就是回跳不能连续两次。

如何解决这个问题呢?很简单,记录一下上次动作。这样我们就可以判断了。我们可以定义如下的数据类型。

struct JUMP {
    int  pos;//位置
    bool act;//动作。false为向后跳,true向前跳

    JUMP(int _pos, bool _act) : pos(_pos), act(_act) {}
    JUMP() { pos=0; act=true; }
};

难点二

在如下的数据

[162,118,178,152,167,100,40,74,199,186,26,73,200,127,30,124,193,84,184,36,103,149,153,9,54,154,133,95,45,198,79,157,64,122,59,71,48,177,82,35,14,176,16,108,111,6,168,31,134,164,136,72,98]
29
98
80

卡了好久。原因是前后是不同的,一个点即可以是往前跳到的,也可以是往后跳到的。不能因为往前跳到了这个点,就不允许这个点以后不让往后跳到了。

我的控制方法是在向后不控制 visit。这里目前我也说不出一个所以然,再仔细查查资料。

难点三

也正是由于可以向后跳,使得我们需要控制向前跳的总次数。根据题目可知 x 的最大值是 2000,a 的最大值是 2000,因此 x+2a 是最大的位置,也就是 6000。操作了这个位置,肯定是到不了家的。

AC 参考代码

const int MAXN=6e3+4;
int cost[MAXN];

struct JUMP {
    int  pos;//位置
    bool act;//动作。false为向后跳,true向前跳

    JUMP(int _pos, bool _act) : pos(_pos), act(_act) {}
    JUMP() { pos=0; act=true; }
};

class Solution {
public:
    int minimumJumps(vector& forbidden, int a, int b, int x) {
        if (0==x) {
            return 0;
        }

        //可见性控制
        vector visit(MAXN, false);
        for (int i=0; i q;
        q.push(JUMP(0, false));
        visit[0]=true;
        int cost=0;//价值

        while (false==q.empty()) {
            cost++;//下一跳价值
            
            int len=q.size();
            for (int i=0; i=0 && false==visit[npos] && false==curr.act) {
                    //合法性判断
                    if (x==npos) {
                        return cost;
                    }
                    //visit[npos]=true;
                    //加入队列
                    q.push(JUMP(npos, true));
                }
            }
        }
        return -1;
    }
};

LeetCode 题解 —— 1654. 到家的最少跳跃次数_第1张图片

时间复杂度

O(N)。

空间复杂度

O(N)。

你可能感兴趣的:(OJ题解,#,LeetCode题解,LeetCode题解,1654,BFS)