【LeetCode】Day208-穿过迷宫的最少移动次数

该问题是一个关于路径优化的问题,使用了BFS(广度优先搜索)策略来寻找从起点到终点的最短路径。在蛇形移动的条件下,考虑了蛇的水平和垂直状态,以及旋转操作,通过更新距离矩阵并避免重复访问同一位置,最终找到达到目标的最小移动次数。时间复杂度和空间复杂度都是O(n^2)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

1210. 穿过迷宫的最少移动次数【困难】

题解

看到最短路径,首先考虑BFS,不行再考虑DP!

广度优先搜索方法的正确性在于:我们一定不会到达同一个位置两次及以上,因为这样必定不是最少的移动次数。

假设当前蛇尾位置(x,y),选择蛇尾位置的好处是旋转操作时,无需进行坐标的转换。

将蛇尾坐标和蛇的水平/竖直状态一起形成一个三元组(x,y,status),其中status=0表示水平状态,1表示竖直状态。

status=0(蛇水平):

  • 【右移】需要保证(x,y+2)是空的单元格;
  • 【下移】需要保证(x+1,y) 和(x+1,y+1) 均是空的单元格;
  • 【顺时针旋转】需要保证 (x+1,y) 和 (x+1,y+1) 均是空的单元格。

status=1(蛇竖直):

  • 【右移】需要保证(x,y+1) 和(x+1,y+1) 均是空的单元格;
  • 【下移】需要保证(x+2,y) 是空的单元格;
  • 【逆时针旋转】需要保证(x,y+1) 和(x+1,y+1) 均是空的单元格;

广度优先搜索解决本题。

class Solution {
    public int minimumMoves(int[][] grid) {
        int n=grid.length;
        int[][][] dist=new int[n][n][2];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                Arrays.fill(dist[i][j],-1);
            }
        }
        dist[0][0][0]=0;
        Queue<int[]>queue=new ArrayDeque<>();
        queue.offer(new int[]{0,0,0});
        while(!queue.isEmpty()){
            int[] point=queue.poll();
            int x=point[0],y=point[1],status=point[2];//(x,y)为蛇尾坐标
            //蛇水平
            if(status==0){
                //右移
                if(y+2<n&&dist[x][y+1][0]==-1&&grid[x][y+2]==0){
                    dist[x][y+1][0]=dist[x][y][0]+1;
                    queue.offer(new int[]{x,y+1,0});
                }
                //下移
                if(x+1<n&&dist[x+1][y][0]==-1&&grid[x+1][y]==0&&grid[x+1][y+1]==0){
                    dist[x+1][y][0]=dist[x][y][0]+1;
                    queue.offer(new int[]{x+1,y,0});
                }
                //顺时针旋转
                if(x+1<n&&y+1<n&&dist[x][y][1]==-1&&grid[x+1][y]==0&&grid[x+1][y+1]==0){
                    dist[x][y][1]=dist[x][y][0]+1;
                    queue.offer(new int[]{x,y,1});
                }
            }
            //蛇竖直
            else{
                //右移
                if(y+1<n&&dist[x][y+1][1]==-1&&grid[x][y+1]==0&&grid[x+1][y+1]==0){
                    dist[x][y+1][1]=dist[x][y][1]+1;
                    queue.offer(new int[]{x,y+1,1});
                }
                //下移
                if(x+2<n&&dist[x+1][y][1]==-1&&grid[x+2][y]==0){
                    dist[x+1][y][1]=dist[x][y][1]+1;
                    queue.offer(new int[]{x+1,y,1});
                }
                //逆时针旋转
                if(x+1<n&&y+1<n&&dist[x][y][0]==-1&&grid[x][y+1]==0&&grid[x+1][y+1]==0){
                    dist[x][y][0]=dist[x][y][1]+1;
                    queue.offer(new int[]{x,y,0});
                }
            }
        }
        return dist[n-1][n-2][0];
    }
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)

空间复杂度: O ( n 2 ) O(n^2) O(n2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值