【每日一题Day310】LC1654到家的最少跳跃次数 | BFS

简介: 【每日一题Day310】LC1654到家的最少跳跃次数 | BFS

到家的最少跳跃次数【LC1654】

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

跳蚤跳跃的规则如下:

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

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

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

思路:最短路问题,BFS

  • **BFS:**寻找最少跳跃次数,所以可以使用最短路径Dijkstra 算法,通过BFS实现,队列元素需要存储当前跳跃次数以及当前位置;
  • **记录状态:**由于跳跃时连续向前次数不受限制,但是不能连续向后跳两次,因此跳跃时还需要记录前一跳跃的状态为向后还是向前;
  • 如果前一状态为向前,那么本次可以向前也可以向后
  • 如果前一状态为向后,那么本次只可以向前
  • 判断是否可以访问:
  • 首先判断最远右边界,由于向前跳跃次数不受限制,避免超时,需要寻找最远右边界【重点】
  • 当前位置不在forbidden数组中
  • 之前没有访问过该状态【位置+方向】

image.png

class Solution {
    public int minimumJumps(int[] forbidden, int a, int b, int x) {
        Set<Integer> vis = new HashSet<>();
        Deque<int[]> pq = new LinkedList<>();// 跳跃次数、当前位置、连续向后跳次数
        int max = 0;       
        for (int f : forbidden){
            vis.add(f);
            max = Math.max(max, f);
        }      
        if (a > b){
            max = x + b;
        }else{
            max = Math.max(max + a + b, x);
        }
        boolean[][] flag = new boolean[max + 1][2];// 向前 向后一次
        flag[0][0] = true;
        pq.addLast(new int[]{0, 0, 0});
        while (!pq.isEmpty()){
            int[] node = pq.pollFirst();
            if (node[1] == x) return node[0]; 
            // 向前
            int forward = node[1] + a;
            if (forward <= max && !vis.contains(forward) && !flag[forward][0]){
                flag[forward][0] = true;
                pq.addLast(new int[]{node[0] + 1, forward, 0});
            }
            // 向后
            int backward = node[1] - b;
            if (node[2] != 1 && backward >= 0 && !vis.contains(backward) && !flag[backward][1]){
                flag[backward][1] = true;
                pq.addLast(new int[]{node[0] + 1, backward, 1});
            }
        }
        return -1;
    }
}


目录
相关文章
|
6月前
【每日一题Day141】LC2379得到 K 个黑块的最少涂色次数 | 滑动窗口
【每日一题Day141】LC2379得到 K 个黑块的最少涂色次数 | 滑动窗口
38 0
|
6月前
【每日一题Day302】LC849到最近的人的最大距离 | 贪心+分类讨论
【每日一题Day302】LC849到最近的人的最大距离 | 贪心+分类讨论
54 0
|
6月前
【每日一题Day167】LC1000合并石头的最低成本 | 区间dp
【每日一题Day167】LC1000合并石头的最低成本 | 区间dp
55 1
【每日一题Day167】LC1000合并石头的最低成本 | 区间dp
|
6月前
|
计算机视觉
【每日一题Day231】LC1240铺瓷砖 | 暴力回溯
【每日一题Day231】LC1240铺瓷砖 | 暴力回溯
55 0
|
6月前
【每日一题Day314】LC1921消灭怪物的最大数量 | 贪心+排序
【每日一题Day314】LC1921消灭怪物的最大数量 | 贪心+排序
46 0
|
6月前
【每日一题Day355】LC1402 做菜顺序 | 贪心+排序
【每日一题Day355】LC1402 做菜顺序 | 贪心+排序
45 0
|
6月前
【每日一题Day319】LC2594修车的最少时间 | 二分答案
【每日一题Day319】LC2594修车的最少时间 | 二分答案
35 0
|
6月前
|
图计算
【每日一题Day274】LC42接雨水 | 单调栈
【每日一题Day274】LC42接雨水 | 单调栈
48 0
|
6月前
【每日一题Day126】LC1140石子游戏Ⅱ | 博弈dp 记忆化搜索
【每日一题Day126】LC1140石子游戏Ⅱ | 博弈dp 记忆化搜索
47 0
|
6月前
【每日一题Day330】LC337打家劫舍Ⅲ | 动态规划
【每日一题Day330】LC337打家劫舍Ⅲ | 动态规划
35 0