leetcode5366. 检查网格中是否存在有效路径

leetcode5366. 检查网格中是否存在有效路径


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

1 表示连接左单元格和右单元格的街道。
2 表示连接上单元格和下单元格的街道。
3 表示连接左单元格和下单元格的街道。
4 表示连接右单元格和下单元格的街道。
5 表示连接左单元格和上单元格的街道。
6 表示连接右单元格和上单元格的街道。在这里插入图片描述
你最开始从左上角的单元格 (0,0) 开始出发,网格中的「有效路径」是指从左上方的单元格 (0,0) 开始、一直到右下方的 (m-1,n-1) 结束的路径。该路径必须只沿着街道走。

注意:你 不能 变更街道。

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

我的思路

dfs查找,分6种情况,当前的是哪一种路,然后下一步要走哪一种路,如果不能走就不去搜索。第一次做这种题,代码还是很不好看的。一堆ifelse可以用switch优化。

class Solution {
    public boolean hasValidPath(int[][] grid) {
        visited=new int[grid.length][grid[0].length];
        visited[0][0]=1;
        dfs(grid,0,0);
        // for(int i=0;i<visited.length;i++){
        //     for(int j=0;j<visited[i].length;j++){
        //         System.out.print(visited[i][j]+" ");
        //     }
        //     System.out.println();
        // }
        return flag;
    }
    public boolean flag=false;
    public int[][]visited;
    public void dfs(int[][]grid,int x,int y){
        //System.out.println("x "+x+"y "+y);
        if(x==grid.length-1&&y==grid[0].length-1){
            flag=true;
            return;
        }
        int[][]direction={{-1,0},{0,1},{1,0},{0,-1}};
        int now=grid[x][y];

        //
        for(int i=0;i<4;i++){
            int nextX=x+direction[i][0];
            int nextY=y+direction[i][1];
            //System.out.println(nextX+" "+nextY);
            if(nextX<0||nextX>grid.length-1||nextY<0||nextY>grid[0].length-1)
              continue;
            int nextP=grid[nextX][nextY];
            if(now==1){
                if((i==0||i==2))
                continue;
                else{
                    if(i==1){
                        if(nextP==2||nextP==4||nextP==6)continue;
                    }else if(i==3){
                        if(nextP==2||nextP==3||nextP==5)continue;
                    }
                }
            }
            if(now==2){
                if((i==1||i==3))
                continue;
                else{
                    if(i==0){
                        if(nextP==1||nextP==5||nextP==6)continue;
                        
                    }else if(i==2){
                        if(nextP==1||nextP==3||nextP==4)continue;
                        
                    }
                }
            }
            if(now==3){
                if((i==0||i==1))
                continue;
                else{
                    if(i==2){
                        if(nextP==1||nextP==4)continue;
                    }else if(i==3){
                        if(nextP==2||nextP==5)continue;
                    }
                }
            }
            if(now==4){
                if((i==0||i==3))
                continue;
                else{
                    if(i==1){
                        if(nextP==2||nextP==6)continue;
                    }else if(i==2){
                        if(nextP==1||nextP==3)continue;
                    }
                }
            }
            if(now==5){
                if((i==2||i==1))
                continue;
                else{
                    if(i==0){
                        if(nextP==1||nextP==6)continue;
                    }else if(i==3){
                        if(nextP==2||nextP==3)continue;
                    }
                }
            }
            if(now==6){
                if((i==2||i==3))
                continue;
                else{
                    if(i==0){
                        if(nextP==1||nextP==5)continue;
                    }else if(i==1){
                        if(nextP==2||nextP==4)continue;
                    }
                }
            }
            if(visited[nextX][nextY]==1)
              continue;
            visited[nextX][nextY]=1;
            dfs(grid,nextX,nextY);
           }
       
    }
}

优化方法

评论区看到的检查网格中是否存在有效路径

class Solution {
public:
    int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//定义四个方向,上下左右
    //建立形状和方向的映射
    int a[7][2] = {{0,0},{2,3},{0,1},{1,2},{1,3},{0,2},{0,3}};
    int n,m;
    bool visited[500][500];
    //判读顶点是否规范
    bool check(int x,int y){
        if(x < 0 || x >= m || y<0 || y >= n){
            return false;
        }
        return true;
    }
    void dfs(int x,int y,vector<vector<int>>& grid){
        if(check(x,y)==false) return;
        visited[x][y] = true;//标记访问
        // cout<<"x="<<x<<'\t'<<"y="<<y<<endl;
        int tmpdir = grid[x][y];//取出该点的街道类型
        for(int i=0;i<2;i++){
            int t = a[tmpdir][i];
            int tx = dir[t][0] + x;
            int ty = dir[t][1] + y;         
            //(tx,ty)是下一跳可到达的点。需要再去判读,该点是否和
            if(check(tx,ty)){
                // cout<<"tx="<<tx<<"\t"<<"ty="<<ty<<endl;
                int tmp = grid[tx][ty];//得到下一步的街道类型
                for(int k=0;k<2;k++){
                    int p = a[tmp][k];//得到该街道的两个方向
                    if(dir[t][0] + dir[p][0]==0 && dir[t][1]+dir[p][1]==0){//判读是否可以走通
                        if(!visited[tx][ty]){
                            dfs(tx,ty,grid);
                        }                    
                    }
                }                
            }
        }
    }
    bool hasValidPath(vector<vector<int>>& grid) {
        m = grid.size();//行数
        n = grid[0].size();//列数
        dfs(0,0,grid);
        if(visited[m-1][n-1] == true){
            return true;//可到达
        }
        return false;
    }
};

多用了一个数组表示当前的路的状态,再根据dir[t][0] + dir[p][0]==0 && dir[t][1]+dir[p][1]==0判断能不能再继续走。

这周的第三道题最后五分钟才写出来,还好也是三道题,基本目标达成了。
leetcode 63/100

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值