leetcode 1391. 检查网格中是否存在有效路径 中等

给你一个 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

分析:从起点开始进行 BFS,用一个队列记录当前可以走到的街道位置,初始时队列里仅有起点的坐标位置。每次进行 BFS 时,检查队列头的坐标,根据它的街道形式,判断能否走到相邻的街和相邻的街道是否已经走到过,如果可以走到并且没有走过,则标记相邻街道已访问并入队,直到队列为空或者走到右下角。最后检查右下角是否走过,如果走过,返回 true,否则返回 false。

cpp 复制代码
class Solution {
public:
    bool hasValidPath(vector<vector<int>>& grid) {
        int x=0,y=0,f=1,m=grid.size(),n=grid[0].size(),flag[m+5][n+5];
        for(int i=0;i<m;++i)
            for(int j=0;j<n;++j)
                flag[i][j]=0;

        stack<pair<int,int>>sta;sta.push({0,0});
        while(!sta.empty())
        {
            int xx=sta.top().first,yy=sta.top().second,f=0;
            flag[xx][yy]=1;
            if(grid[xx][yy]==1)
            {
                if(yy+1<n&&flag[xx][yy+1]==0&&(grid[xx][yy+1]==3||grid[xx][yy+1]==5||grid[xx][yy+1]==1))
                    sta.push({xx,yy+1}),f=1;
                if(yy-1>=0&&flag[xx][yy-1]==0&&(grid[xx][yy-1]==4||grid[xx][yy-1]==6||grid[xx][yy-1]==1))
                    sta.push({xx,yy-1}),f=1;
            }
            else if(grid[xx][yy]==2)
            {
                if(xx+1<m&&flag[xx+1][yy]==0&&(grid[xx+1][yy]==5||grid[xx+1][yy]==6||grid[xx+1][yy]==2))
                    sta.push({xx+1,yy}),f=1;
                if(xx-1>=0&&flag[xx-1][yy]==0&&(grid[xx-1][yy]==3||grid[xx-1][yy]==4||grid[xx-1][yy]==2))
                    sta.push({xx-1,yy}),f=1;
            }
            else if(grid[xx][yy]==3)
            {
                if(xx+1<m&&flag[xx+1][yy]==0&&(grid[xx+1][yy]==5||grid[xx+1][yy]==6||grid[xx+1][yy]==2))
                    sta.push({xx+1,yy}),f=1;
                if(yy-1>=0&&flag[xx][yy-1]==0&&(grid[xx][yy-1]==4||grid[xx][yy-1]==6||grid[xx][yy-1]==1))
                    sta.push({xx,yy-1}),f=1;
            }
            else if(grid[xx][yy]==4)
            {
                if(xx+1<m&&flag[xx+1][yy]==0&&(grid[xx+1][yy]==5||grid[xx+1][yy]==6||grid[xx+1][yy]==2))
                    sta.push({xx+1,yy}),f=1;
                if(yy+1<n&&flag[xx][yy+1]==0&&(grid[xx][yy+1]==3||grid[xx][yy+1]==5||grid[xx][yy+1]==1))
                    sta.push({xx,yy+1}),f=1;
            }
            else if(grid[xx][yy]==5)
            {
                if(xx-1>=0&&flag[xx-1][yy]==0&&(grid[xx-1][yy]==3||grid[xx-1][yy]==4||grid[xx-1][yy]==2))
                    sta.push({xx-1,yy}),f=1;
                if(yy-1>=0&&flag[xx][yy-1]==0&&(grid[xx][yy-1]==4||grid[xx][yy-1]==6||grid[xx][yy-1]==1))
                    sta.push({xx,yy-1}),f=1;
            }
            else if(grid[xx][yy]==6)
            {
                if(xx-1>=0&&flag[xx-1][yy]==0&&(grid[xx-1][yy]==3||grid[xx-1][yy]==4||grid[xx-1][yy]==2))
                    sta.push({xx-1,yy}),f=1;
                if(yy+1<n&&flag[xx][yy+1]==0&&(grid[xx][yy+1]==3||grid[xx][yy+1]==5||grid[xx][yy+1]==1))
                    sta.push({xx,yy+1}),f=1;
            }
            if(!f)sta.pop();
        }
        if(flag[m-1][n-1]==1)return true;
        return false;
    }
};
相关推荐
血小板要健康6 小时前
链表 阶段算法总结
java·数据结构·笔记·算法·leetcode·链表
a187927218316 小时前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解
青 春 记 忆8 小时前
LeetCode 350. 两个数组的交集 II|Python 解法详解
python·算法·leetcode
圣保罗的大教堂13 小时前
leetcode 3903. 最小稳定下标 I 简单
leetcode
sylviiiiiia13 小时前
Leetcode hot100 多数元素/相交链表/反转链表
算法·leetcode·链表
CoderYanger13 小时前
A.每日一题:3622. 判断整除性
java·程序人生·算法·leetcode·面试·职场和发展·蓝桥杯
rannn_11114 小时前
【力扣hot100】动态规划专题|70、118、198、279、322、139、300、152、416、32
算法·leetcode·动态规划
我不会起名字32214 小时前
一天一道算法题(26):栈的简单应用
java·数据结构·python·算法·leetcode·golang·
a1879272183115 小时前
【算法】动态规划入门:从打家劫舍到状态设计的三堂课
算法·leetcode·动态规划·dp·回溯·暴力
Tisfy1 天前
LeetCode 3876.构造奇偶一致的数组 II:三种情况分类讨论(其实还是脑筋急转弯)
算法·leetcode·题解·脑筋急转弯