【Leetcode】490. The Maze

题目地址:

https://leetcode.com/problems/the-maze/

给定一个二维 0 − 1 0-1 01矩阵, 0 0 0代表空地, 1 1 1代表障碍物。在某个空地上有个小球,它可以沿着四个方向滑动,每次滑动时只有遇到边界或者障碍物才会停下来。再给定一个空地作为终点,问该小球是否可能滑到终点。

思路是BFS。一步一步向外扩展,直到走到终点或者扩展不下去了为止。代码如下:

import java.util.*;

public class Solution {
    public boolean hasPath(int[][] maze, int[] start, int[] destination) {
        if (maze == null || maze.length == 0 || maze[0].length == 0) {
            return false;
        }
        // 四个方向
        int[][] dirs = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        
        Queue<int[]> queue = new LinkedList<>();
        // 判断某个位置是否访问过
        boolean[][] visited = new boolean[maze.length][maze[0].length];
        queue.offer(new int[]{start[0], start[1]});
        visited[start[0]][start[1]] = true;
        
        while (!queue.isEmpty()) {
            int[] cur = queue.poll();
            for (int[] next : getNexts(cur[0], cur[1], maze, dirs, visited)) {
            	// 如果next等于终点,说明终点可以到达了,返回true
                if (Arrays.equals(next, destination)) {
                    return true;
                }
                
                queue.offer(next);
                visited[next[0]][next[1]] = true;
            }
        }
        
        // 队列为空意味着无法扩展下去,返回false
        return false;
    }
    
    // 返回从maze[x][y]沿着四个方向滑动会停下来的地方
    private List<int[]> getNexts(int x, int y, int[][] maze, int[][] dirs, boolean[][] visited) {
        List<int[]> nexts = new ArrayList<>();
        for (int i = 0; i < dirs.length; i++) {
            int dx = dirs[i][0], dy = dirs[i][1];
            int step = 1;
            while (inBound(x + step * dx, y + step * dy, maze) && maze[x + step * dx][y + step * dy] == 0) {
                step++;
            }
            // 回退一格才是真正停下来的地方
            step--;
            int nextX = x + step * dx, nextY = y + step * dy;
            if (!visited[nextX][nextY]) {
                nexts.add(new int[]{nextX, nextY});
            }
        }
        
        return nexts;
    }
    
    private boolean inBound(int x, int y, int[][] maze) {
        return 0 <= x && x < maze.length && 0 <= y && y < maze[0].length;
    }
}

时空复杂度 O ( m n ) O(mn) O(mn)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值