LeetCode第156场周赛:5208. 穿过迷宫的最少移动次数(BFS)

5208. 穿过迷宫的最少移动次数

 显示英文描述 

我的提交返回竞赛

  • 用户通过次数45
  • 用户尝试次数84
  • 通过次数48
  • 提交次数145
  • 题目难度Hard

你还记得那条风靡全球的贪吃蛇吗?

我们在一个 n*n 的网格上构建了新的迷宫地图,蛇的长度为 2,也就是说它会占去两个单元格。蛇会从左上角((0, 0) 和 (0, 1))开始移动。我们用 0 表示空单元格,用 1 表示障碍物。蛇需要移动到迷宫的右下角((n-1, n-2) 和 (n-1, n-1))。

每次移动,蛇可以这样走:

  • 如果没有障碍,则向右移动一个单元格。并仍然保持身体的水平/竖直状态。
  • 如果没有障碍,则向下移动一个单元格。并仍然保持身体的水平/竖直状态。
  • 如果它处于水平状态并且其下面的两个单元都是空的,就顺时针旋转 90 度。蛇从((r, c)(r, c+1))移动到 ((r, c)(r+1, c))。
  • 如果它处于竖直状态并且其右面的两个单元都是空的,就逆时针旋转 90 度。蛇从((r, c)(r+1, c))移动到((r, c)(r, c+1))。

返回蛇抵达目的地所需的最少移动次数。

如果无法到达目的地,请返回 -1

 

示例 1:

输入:grid = [[0,0,0,0,0,1],
               [1,1,0,0,1,0],
               [0,0,0,0,1,1],
               [0,0,1,0,1,0],
               [0,1,1,0,0,0],
               [0,1,1,0,0,0]]
输出:11
解释:
一种可能的解决方案是 [右, 右, 顺时针旋转, 右, 下, 下, 下, 下, 逆时针旋转, 右, 下]。

示例 2:

输入:grid = [[0,0,1,1,1,1],
               [0,0,0,0,1,1],
               [1,1,0,0,0,1],
               [1,1,1,0,0,1],
               [1,1,1,0,0,1],
               [1,1,1,0,0,0]]
输出:9

 

提示:

  • 2 <= n <= 100
  • 0 <= grid[i][j] <= 1
  • 蛇保证从空单元格开始出发。

思路:辣鸡题一道,典型的BFS题,我们可以定义一个node类标记状态,其中状态无非就是蛇尾、蛇头坐标,当前是否是水平或者垂直,已经走到当前状态的步骤。flag数组表示蛇尾坐标为x,y并且当前是水平或者垂直的状态是否已经遍历过。

class Solution {
	
	class node
	{
		int x1,x2,y1,y2,state,step;
		public node(int x1,int y1,int x2,int y2,int state,int step)
		{
			this.x1=x1;
			this.y1=y1;
			this.x2=x2;
			this.y2=y2;
			this.state=state;
			this.step=step;
		}
	}
	
	boolean[][][] flag=new boolean[105][105][2];
	
    public int minimumMoves(int[][] grid) {
    	int n=grid.length;
        node start=new node(0,0,0,1,0,0); flag[0][0][0]=true;
        node end=new node(n-1,n-2,n-1,n-1,0,0);
        Queue<node> q=new LinkedList();
        q.add(start);
        while(!q.isEmpty())
        {
        	 node now=q.poll();
        	 if(isOk(now,end))
        		 return now.step;
        	 int dx1,dy1,dx2,dy2;
        	 if(now.state==0)
        	 {
            	  dx1=now.x1;dy1=now.y1+1;
            	  dx2=now.x2;dy2=now.y2+1;
	        	 if(dy1<n && dy2<n && !flag[dx1][dy1][0] &&	grid[dx2][dy2]==0)
	        	 {
	        		 flag[dx1][dy1][0]=true;
	        		 q.add(new node(dx1,dy1,dx2,dy2,0,now.step+1));
	        	 }
	        	 if(dx1+1<n && grid[dx1+1][now.y1]==0 && grid[dx1+1][now.y2]==0)
	        	 {
	        		 if(!flag[dx1+1][now.y1][0])
	        		 {
	        			 flag[dx1+1][now.y1][0]=true;
	        			 q.add(new node(dx1+1,now.y1,dx2+1,now.y2,0,now.step+1));
	        		 }
	        		 if(!flag[dx1][now.y1][1])
	        		 {
	        			 flag[dx1][now.y1][1]=true;
	        			 q.add(new node(dx1,now.y1,dx1+1,now.y1,1,now.step+1));
	        		 }
	        	 }
        	 }
        	 else
        	 {
        		 dx1=now.x1+1;dy1=now.y1;
        		 dx2=now.x2+1;dy2=now.y2;
        		 if(dx1<n && dx2<n && grid[dx2][dy2]==0 && !flag[dx1][dy1][1])
        		 {
        			 flag[dx1][dy1][1]=true;
        			 q.add(new node(dx1,dy1,dx2,dy2,1,now.step+1));
        		 }
        		 if(dy1+1<n && grid[now.x1][now.y1+1]==0 && grid[now.x2][now.y2+1]==0)
        		 {
        			 if(!flag[now.x1][now.y1+1][1])
        			 {
	        			 flag[now.x1][now.y1+1][1]=true;
	        			 q.add(new node(now.x1,now.y1+1,now.x2,now.y2+1,1,now.step+1));
        			 }
        			 if(!flag[now.x1][now.y1][0])
        			 {
        				 flag[now.x1][now.y1][0]=true;
        				 q.add(new node(now.x1,now.y1,now.x1,now.y1+1,0,now.step+1));
        			 }
        		 }
        		 
        	 }
        }      
        return -1;
    }
    
    private boolean isOk(node a,node b)
    {
    	if(a.x1==b.x1 && a.x2==b.x2 && a.y1==b.y1 && a.y2==b.y2)
    		return true;
    	return false;
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值