文章目录

  • 1. 题目
  • 2. 解题
    • 2.1 BFS
    • 2.2 爆栈的DFS
    • 2.3 不爆栈的DFS

1. 题目

给你一个 m x n 的网格 grid。网格里的每个单元都代表一条街道。grid[i][j] 的街道可以是:

  • 1 表示连接左单元格和右单元格的街道。
  • 2 表示连接上单元格和下单元格的街道。
  • 3 表示连接左单元格和下单元格的街道。
  • 4 表示连接右单元格和下单元格的街道。
  • 5 表示连接左单元格和上单元格的街道。
  • 6 表示连接右单元格和上单元格的街道。

    你最开始从左上角的单元格 (0,0) 开始出发,网格中的「有效路径」是指从左上方的单元格 (0,0) 开始、一直到右下方的 (m-1,n-1) 结束的路径。该路径必须只沿着街道走。

注意:你 不能 变更街道。

如果网格中存在有效的路径,则返回 true,否则返回 false 。

示例 1:

输入:grid = [[2,4,3],[6,5,2]]
输出:true
解释:如图所示,你可以从 (0, 0) 开始,访问网格中的所有单元格并到达 (m - 1, n - 1) 。

示例 2:

输入:grid = [[1,2,1],[1,2,1]]
输出:false
解释:如图所示,单元格 (0, 0) 上的街道没有与任何其他单元格上的街道相连,你只会停在 (0, 0) 处。示例 3:
输入:grid = [[1,1,2]]
输出:false
解释:你会停在 (0, 1),而且无法到达 (0, 2) 。示例 4:
输入:grid = [[1,1,1,1,1,1,3]]
输出:true示例 5:
输入:grid = [[2],[2],[2],[2],[2],[2],[6]]
输出:true提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
1 <= grid[i][j] <= 6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/check-if-there-is-a-valid-path-in-a-grid
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

2.1 BFS

  • 广度优先搜索
class Solution {vector<vector<int>> d = {{0,1},{1,0},{-1,0},{0,-1}};//右0,下1,上2,左3vector<vector<vector<int>>> dir = {{},{d[0],d[3]},{d[1],d[2]},{d[1],d[3]},{d[0],d[1]},{d[2],d[3]},{d[0],d[2]}};//网格可走的方向int m,n;
public:bool hasValidPath(vector<vector<int>>& grid) {m = grid.size(), n = grid[0].size();vector<vector<bool>> visited(m, vector<bool>(n,false));visited[0][0] = true;queue<vector<int>> q;q.push({0,0});int x,y,x0,y0,k,dx,dy;while(!q.empty()){x0 = q.front()[0];y0 = q.front()[1];if(x0==m-1 && y0==n-1)return true;q.pop();for(k = 0; k < dir[grid[x0][y0]].size(); ++k){   //网格可走方向dx = dir[grid[x0][y0]][k][0];dy = dir[grid[x0][y0]][k][1];x = x0+dx;y = y0+dy;if(x>=0 && x<m && y>=0 && y<n && !visited[x][y] && isok(grid,dx,dy,x,y)){visited[x][y] = true;q.push({x,y});}}}return false;}bool isok(vector<vector<int>>& grid, int &dx, int &dy, int &x, int &y){ //dx dy 走过来的方向,在位置 x y 中有对应的接口,则可以走过来if(dx == 1 && dy ==0)//往下走,对应x,y处 '上' 要开着{if(grid[x][y]==2 || grid[x][y]==5 || grid[x][y]==6)return true;}else if(dx == 0 && dy == 1)//右   --左{if(grid[x][y]==1 || grid[x][y]==3 || grid[x][y]==5)return true;}else if(dx == -1 && dy == 0)//上 ---下{if(grid[x][y]==2 || grid[x][y]==3 || grid[x][y]==4)return true;}else if(dx == 0 && dy == -1)//左--- 右{if(grid[x][y]==1 || grid[x][y]==4 || grid[x][y]==6)return true;}return false;}
};

2.2 爆栈的DFS

  • dfs 方法爆栈,代码如下,请大佬帮忙看看什么原因

class Solution {vector<vector<int>> d = {{0,1},{1,0},{-1,0},{0,-1}};//右0,下1,上2,左3vector<vector<vector<int>>> dir = {{},{d[0],d[3]},{d[1],d[2]},{d[1],d[3]},{d[0],d[1]},{d[2],d[3]},{d[0],d[2]}};bool found = false;int m,n;
public:bool hasValidPath(vector<vector<int>>& grid) {m = grid.size(), n = grid[0].size();vector<vector<bool>> visited(m, vector<bool>(n,false));visited[0][0] = true;dfs(grid,0,0,visited);return found;}void dfs(vector<vector<int>>& grid, int i, int j,vector<vector<bool>> &visited){if(found)return;if(i==m-1 && j==n-1){found = true;return;}int x, y, k, dx, dy;for(k = 0; k < dir[grid[i][j]].size(); ++k){dx = dir[grid[i][j]][k][0];dy = dir[grid[i][j]][k][1];x = i+dx;y = j+dy;if(x>=0 && x<m && y>=0 && y<n && !visited[x][y] && isok(grid,dx,dy,x,y)){visited[x][y] = true;dfs(grid,x,y,visited);visited[x][y] = false;}}}bool isok(vector<vector<int>>& grid, int &dx, int &dy, int &x, int &y){if(dx == 1 && dy ==0)//往下走,对应x,y处 '上' 要开着{if(grid[x][y]==2 || grid[x][y]==5 || grid[x][y]==6)return true;}else if(dx == 0 && dy == 1)//右   --左{if(grid[x][y]==1 || grid[x][y]==3 || grid[x][y]==5)return true;}else if(dx == -1 && dy == 0)//上 ---下{if(grid[x][y]==2 || grid[x][y]==3 || grid[x][y]==4)return true;}else if(dx == 0 && dy == -1)//左--- 右{if(grid[x][y]==1 || grid[x][y]==4 || grid[x][y]==6)return true;}return false;}
};

2.3 不爆栈的DFS

  • isok 函数 的 int 变量去掉 & 就不报错了,什么情况。。。
class Solution {vector<vector<int>> d = {{0,1},{1,0},{-1,0},{0,-1}};//右0,下1,上2,左3vector<vector<vector<int>>> dir = {{},{d[0],d[3]},{d[1],d[2]},{d[1],d[3]},{d[0],d[1]},{d[2],d[3]},{d[0],d[2]}};bool found = false;int m,n;
public:bool hasValidPath(vector<vector<int>>& grid) {m = grid.size(), n = grid[0].size();vector<vector<bool>> visited(m, vector<bool>(n,false));visited[0][0] = true;dfs(grid,0,0,visited);return found;}void dfs(vector<vector<int>>& grid, int i, int j,vector<vector<bool>> &visited){if(found)return;if(i==m-1 && j==n-1){found = true;return;}int x, y, k, dx, dy;for(k = 0; k < dir[grid[i][j]].size(); ++k){dx = dir[grid[i][j]][k][0];dy = dir[grid[i][j]][k][1];x = i+dx;y = j+dy;if(x>=0 && x<m && y>=0 && y<n && !visited[x][y] && isok(grid,dx,dy,x,y)){visited[x][y] = true;dfs(grid,x,y,visited);visited[x][y] = false;}}}bool isok(vector<vector<int>> &grid, int dx, int dy, int x, int y){if(dx == 1 && dy ==0)//往下走,对应x,y处 '上' 要开着{if(grid[x][y]==2 || grid[x][y]==5 || grid[x][y]==6)return true;}else if(dx == 0 && dy == 1)//右   --左{if(grid[x][y]==1 || grid[x][y]==3 || grid[x][y]==5)return true;}else if(dx == -1 && dy == 0)//上 ---下{if(grid[x][y]==2 || grid[x][y]==3 || grid[x][y]==4)return true;}else if(dx == 0 && dy == -1)//左--- 右{if(grid[x][y]==1 || grid[x][y]==4 || grid[x][y]==6)return true;}return false;}
};

LeetCode 1391. 检查网格中是否存在有效路径(BFS)相关推荐

  1. LeetCode 5366. 检查网格中是否存在有效路径

    5366. 检查网格中是否存在有效路径 思路:分好上下左右的情况即可,比bfs,dfs那些简单一点.从0,0开始,走到m-1,n-1就返回true,go_next(判断下一步) class Solut ...

  2. [leetcode]5366. 检查网格中是否存在有效路径

    解题思路:BFS AC的代码: struct Point {int x,y;int d;Point(int _x, int _y, int _d){x = _x, y = _y, d = _d;} } ...

  3. LeetCode 2042. 检查句子中的数字是否递增

    文章目录 1. 题目 2. 解题 1. 题目 句子是由若干 token 组成的一个列表,token 间用 单个 空格分隔,句子没有前导或尾随空格. 每个 token 要么是一个由数字 0-9 组成的不 ...

  4. LeetCode 1293. 网格中的最短路径(DP/BFS)

    1. 题目 给你一个 m * n 的网格,其中每个单元格不是 0(空)就是 1(障碍物). 每一步,您都可以在空白单元格中上.下.左.右移动. 如果您 最多 可以消除 k 个障碍物,请找出从左上角 ( ...

  5. [Leetcode][第257题][JAVA][二叉树的所有路径][BFS][DFS]

    [问题描述][简单] [解答思路] 1. DFS 时间复杂度:O(N^2) 空间复杂度:O(N^2) class Solution {public List<String> binaryT ...

  6. LeetCode简单题之检查句子中的数字是否递增

    题目 句子是由若干 token 组成的一个列表,token 间用 单个 空格分隔,句子没有前导或尾随空格.每个 token 要么是一个由数字 0-9 组成的不含前导零的 正整数 ,要么是一个由小写英文 ...

  7. Leetcode刷题100天—2042. 检查句子中的数字是否递增—day70

    前言: 作者:神的孩子在歌唱 大家好,我叫智 2042. 检查句子中的数字是否递增 难度简单2收藏分享切换为英文接收动态反馈 句子是由若干 token 组成的一个列表,token 间用 单个 空格分隔 ...

  8. SAP ABAP ALV控制显示的网格中的每一个字段属性

    字段目录是用来控制ALV显示的网格中每个字段的属性的,比如字段的顺序,对齐方式,可编辑状态,颜色,等等.常用的字段如下: row_pos:默认值为0,可选值为1.2.3,既最大分3级别显示 field ...

  9. 【Unity3D】材质 Material ( 材质简介 | 创建材质 | 设置材质属性 | 对 3D 物体应用材质 | 资源拖动到 Inspector 检查器中的 Material 属性中 )

    文章目录 一.材质 Material 简介 二.创建材质 三.设置材质属性 四.对 3D 物体应用材质 五.资源拖动到 Inspector 检查器中的 Material 属性中 一.材质 Materi ...

最新文章

  1. springboot 分层_限量!阿里Spring Boot成长笔记终开源!理论实战满满
  2. MonoDevelop 1.0 和 Mono 1.9(2.0 beta)发布了
  3. UA MATH566 统计理论 Fisher信息量的性质上
  4. Python Django设置中文语言及时区
  5. 成功人士都有的好习惯
  6. Windows Phone 内容滑动切换实现
  7. liux 常用操作命令
  8. 解决Tocmat6.x的catalina.out日志不断增加问题
  9. Python3标准库built-in、itertools、functools中的生成器
  10. 用“无线诊断”工具解决 Mac 出现的 WiFi 连接问题
  11. yb3防爆电机型号含义_温州出租大型发电机定做-智慧动力机械设备租赁
  12. 02_创建 CA 根证书和秘钥
  13. hypermesh中怎么设置支反力(反作用力)
  14. 前端CSS学习(第3、4天)
  15. Linux系统怎么复制文件夹下的全部文件到另外文件夹?
  16. AJAX_入门经典案例
  17. 网易python笔试题_2017秋季网易校园招聘编程题和个人解答(python)
  18. amoled和super amoled的区别 amoled和super amoled哪个更好
  19. 服务器c盘有个inetpub文件夹,Win10正式版C盘inetpub文件夹可以删除吗 Win10正式版C盘inetpub文件夹删不掉怎么办...
  20. UDP就一定比TCP快吗? 看明白这三动图就清晰了

热门文章

  1. C#中的DBNull、Null、String.Empty和“”
  2. 网络:传输层 TCP报文格式解析
  3. [NOI2019]回家路线
  4. Sublime Text3(mac)一些插件和快捷键
  5. Maven整合Spring3.0+Mybatis3.2+Struts2.3+查找坐标+jar包依赖(五)
  6. OpenGL于MFC使用汇总(三)——离屏渲染
  7. Java设计模式-外观模式(Facade)
  8. 简述C++程序编写的过程
  9. C# WebBrower1控件提示“该文档已被修改,是否保存修改结果”解决方法 .
  10. 利用SharePoint Designer开发可循环工作流