到达角落需要移除障碍物的最小数目[带优先级的BFS]

前言

BFS作为图遍历的基础遍历,是操作图的基本功,而有时候并不是每条边权重都是一样的,此时就需要选出最优路径先走,把位置先占着。可通过优先队列来取得最优路径,建好堆,一次logN就能拿到最优路径。

一、到达角落需要移除障碍物的最小数目

在这里插入图片描述

二、带优先级的BFS

1、DFS超时练习(即使剪枝,过于暴力)

// dfs超时。
public class MinimumObstacles {
    /*
    dfs从起点到终点,记录障碍个数。选取最小障碍数。
     */
    public int minimumObstacles(int[][] grid) {
        dfs(grid, 0, 0, 0);
        return min;
    }

    int min = 1 << 30;

    private void dfs(int[][] grid, int i, int j, int cur) {
        // 剪枝,当走这条路需要去除的障碍物太多时,则排除此路。
        if (cur >= min) return;
        int m = grid.length, n = grid[0].length;
        if (i == -1 || -1 == j || i == m || n == j || grid[i][j] == -1) return;

        if (grid[i][j] == 1) ++cur;

        if (i == m - 1 && j == n - 1) {
            if (cur < min) min = cur;
            return;
        }
        int val = grid[i][j];
        grid[i][j] = -1;// 表示该格子已经被访问过。
        dfs(grid, i - 1, j, cur);
        dfs(grid, i + 1, j, cur);
        dfs(grid, i, j - 1, cur);
        dfs(grid, i, j + 1, cur);
        grid[i][j] = val;// 回溯之后,要表示该格子没有被走过。
    }
}

2、带优先级的BFS

class MinimumObstacles2 {
    /*
    变种bfs--优先级bfs + 原地空间利用,记录路径上的障碍数.
    但是不同路径走到相同格子会有选择问题,要选择到该格子碰到的最小障碍物,则需要对障碍物进行排序,选障碍物少路径bfs.
     */
    public int minimumObstacles(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        // 优先级bfs用到的优先队列。
        PriorityQueue<int[]> pQue = new PriorityQueue<>(Comparator.comparingInt(p -> p[0]));
        int[] init = new int[3];//分别表示到达当前格子经过的障碍数、当前格子的横坐标、纵坐标。
        pQue.add(init);
        while (true) {
            int[] cur = pQue.poll();
            int w = cur[0], i = cur[1], j = cur[2];
            if (i == m - 1 && j == n - 1) return w;
            else if (i >= 0 && 0 <= j && i < m && n > j && grid[i][j] != -1) {
                pQue.offer(new int[]{w + grid[i][j], i - 1, j});
                pQue.offer(new int[]{w + grid[i][j], i + 1, j});
                pQue.offer(new int[]{w + grid[i][j], i, j - 1});
                pQue.offer(new int[]{w + grid[i][j], i, j + 1});
                // 设置该节点已在最优路径上了。
                grid[i][j] = -1;
            }
            // else的情况,就是当前ij不合法或者该节点被优先级高的路径走过。
        }
    }
}

总结

1)如何解决带权重的图,起点到终点的最短路径,可用优先队列 + BFS每层从队列中选出最优路径再往前走。

参考文献

[1] LeetCode 到达角落需要移除障碍物的最小数目

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值