lintcode 1446 · 01矩阵走路问题 【两次BFS, VIP 中等 1也计算距离,但是不入队列】

题目链接,描述

https://www.lintcode.com/problem/1446

java 复制代码
给定一个大小为 n*m 的 01 矩阵 grid ,1 是墙,0 是路,你现在可以把 grid 中的一个 1 变成 0,请问从左上角走到右下角是否有路可走?如果有路可走,最少要走多少步?

1≤n≤1∗10^3

1≤m≤1∗10^3
 
样例
样例 1:

输入:a = [[0,1,0,0,0],[0,0,0,1,0],[1,1,0,1,0],[1,1,1,1,0]] 
输出:7
解释:将(0,1)处的 `1` 变成 `0`,最短路径如下:
 (0,0)->(0,1)->(0,2)->(0,3)->(0,4)->(1,4)->(2,4)->(3,4) 其他长度为 `7` 的方案还有很多,这里不一一列举。
样例 2:

输入:a = [[0,1,1],[1,1,0],[1,1,0]]
输出:-1 
解释:不管把哪个 `1` 变成 `0`,都没有可行的路径。

思路、前置知识

 两次BFS

 两次BFS,从第一个位置开始得到距离数组arrS
 从最后一个位置开始得到距离数组arrE
 和常规BFS不同的时,遇到1也统计距离,但是该位置点不进入队列
 最后循环每个下标,检查2个数组的距离和是否都小于int最大值,结果就在这些下标里

参考代码

java 复制代码
public class Solution {
    /**
     * @param grid: The gird
     * @return: Return the steps you need at least
     */
    public int getBestRoad(int[][] grid) {
        //两次BFS,从第一个位置开始得到距离数组arrS
        // 从最后一个位置开始得到距离数组arrE
        //和常规BFS不同的时,遇到1也统计距离,但是该位置点不进入队列
        //最后循环每个下标,检查2个数组的距离和是否都小于int最大值,结果就在这些下标里
        if (grid == null || grid.length == 0 || grid[0].length == 0)
            return 0;

        int n = grid.length, m = grid[0].length;
        int len = n * m; //二维变一维
        int[] arrS = new int[len];
        int[] arrE = new int[len];

        Arrays.fill(arrS, Integer.MAX_VALUE);
        Arrays.fill(arrE, Integer.MAX_VALUE);


        bfs(0, 0, arrS, grid);  //从出发点开始统计距离
        bfs(n - 1, m - 1, arrE, grid); //从终点开始统计距离
        int ans =Integer.MAX_VALUE;

        for (int i = 0; i <n ; i++) {
            for (int j = 0; j <m ; j++) {
                int index = i*m+j;
                if(arrS[index] <Integer.MAX_VALUE && arrE[index] <Integer.MAX_VALUE){

                    ans = Math.min(ans,arrS[index]+arrE[index]);
                }
            }
        }
        return ans < Integer.MAX_VALUE? ans:-1;
    }

    public static void bfs(int x, int y, int[] dis, int[][] arr) {
        Queue<Integer> q = new LinkedList<>();
        Set<Integer> visited = new HashSet<>();
        int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}}; //上下左右
        int n = arr.length,m= arr[0].length;

        q.add(x*m+y);
        visited.add(x*m+y);
        dis[x*m+y] = 0;

        int step =0;

        while (!q.isEmpty()){
            step++;
            int size = q.size();
            for (int i = 0; i <size ; i++) {
                int poll = q.poll();
                int x1 = poll/m;  //一维坐标转二维横坐标
                int y1 = poll-x1*m; //一维坐标转二纵横坐标

                for (int[] dir : dirs) {
                    int x2=x1+dir[0],y2=y1+dir[1];
                    if(x2>=0 && x2<n && y2>=0 && y2<m){
                        int index2 = x2*m+y2;
                        if(visited.contains(index2)) continue;
                        dis[index2] = step; //不管是0还是1都要统计距离
                        visited.add(index2);
                        //只有空地才继续向外扩展
                        if(arr[x2][y2] ==0){
                            q.add(index2);
                        }
                    }
                }
            }
        }
    }
}
相关推荐
小码农<^_^>3 分钟前
优选算法精品课--滑动窗口算法(一)
算法
羊小猪~~5 分钟前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
软工菜鸡30 分钟前
预训练语言模型BERT——PaddleNLP中的预训练模型
大数据·人工智能·深度学习·算法·语言模型·自然语言处理·bert
南宫生33 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
AI视觉网奇1 小时前
sklearn 安装使用笔记
人工智能·算法·sklearn
JingHongB1 小时前
代码随想录算法训练营Day55 | 图论理论基础、深度优先搜索理论基础、卡玛网 98.所有可达路径、797. 所有可能的路径、广度优先搜索理论基础
算法·深度优先·图论
weixin_432702261 小时前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
小冉在学习1 小时前
day52 图论章节刷题Part04(110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长 )
算法·深度优先·图论
Repeat7151 小时前
图论基础--孤岛系列
算法·深度优先·广度优先·图论基础
小冉在学习1 小时前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论