Leetcode: The Maze(Unsolved locked problem)
There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolling up, down, left or right, but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction. Given the ball's start position, the destination and the maze, determine whether the ball could stop at the destination. The maze is represented by a binary 2D array. 1 means the wall and 0 means the empty space. You may assume that the borders of the maze are all walls. The start and destination coordinates are represented by row and column indexes. Example 1 Input 1: a maze represented by a 2D array 0 0 1 0 0
0 0 0 0 0
0 0 0 1 0
1 1 0 1 1
0 0 0 0 0 Input 2: start coordinate (rowStart, colStart) = (0, 4)
Input 3: destination coordinate (rowDest, colDest) = (4, 4) Output: true
Explanation: One possible way is : left -> down -> left -> down -> right -> down -> right.Example 2 Input 1: a maze represented by a 2D array 0 0 1 0 0
0 0 0 0 0
0 0 0 1 0
1 1 0 1 1
0 0 0 0 0 Input 2: start coordinate (rowStart, colStart) = (0, 4)
Input 3: destination coordinate (rowDest, colDest) = (3, 2) Output: false
Explanation: There is no way for the ball to stop at the destination.Note:
There is only one ball and one destination in the maze.
Both the ball and the destination exist on an empty space, and they will not be at the same position initially.
The given maze does not contain border (like the red rectangle in the example pictures), but you could assume the border of the maze are all walls.
The maze contains at least 2 empty spaces, and both the width and height of the maze won't exceed 100.
- Search in the four possible directions when coming to a stopping point (i.e. a new starting point).
- Keep track of places that you already started at in case you roll back to that point.
public class Solution {
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
boolean[][] startedHere = new boolean[maze.length][maze[0].length]; // mark visited starting points
return dfs(maze, startedHere, start, destination);
} private boolean dfs(int[][] maze, boolean[][] startedHere, int[] start, int[] destination) {
if (startedHere[start[0]][start[1]]) return false;
if (Arrays.equals(start, destination)) return true; startedHere[start[0]][start[1]] = true; // in case we roll back to a point we already started at BiPredicate<Integer, Integer> roll = (rowInc, colInc) -> {
int row = start[0], col = start[1]; // init new start row and col
while (canRoll(maze, row + rowInc, col + colInc)) {
row += rowInc;
col += colInc;
}
return dfs(maze, startedHere, new int[]{row, col}, destination); // pass in new start to dfs
}; if (roll.test(1, 0)) return true; // roll up
if (roll.test(0, 1)) return true; // roll right
if (roll.test(-1, 0)) return true; // roll down
if (roll.test(0, -1)) return true; // roll left return false; // return false if no paths led to destination
} private boolean canRoll(int[][] maze, int row, int col) {
if (row >= maze.length || row < 0 || col >= maze[0].length || col < 0) return false; // stop at borders
return maze[row][col] != 1; // stop at walls (1 -> wall)
}
}
UPDATE: Also including one without using BiPredicate on every recursive call since it runs faster
public class Solution { private static final int[] DIRECTIONS = { 0, 1, 0, -1, 0 }; public boolean hasPath(int[][] maze, int[] start, int[] destination) {
boolean[][] startedHere = new boolean[maze.length][maze[0].length];
return dfs(maze, startedHere, start, destination);
} private boolean dfs(int[][] maze, boolean[][] startedHere, int[] start, int[] destination) {
if (startedHere[start[0]][start[1]]) return false;
if (Arrays.equals(start, destination)) return true; startedHere[start[0]][start[1]] = true; for (int i = 0; i < DIRECTIONS.length - 1; i++) {
int[] newStart = roll(maze, start[0], start[1], DIRECTIONS[i], DIRECTIONS[i + 1]);
if (dfs(maze, startedHere, newStart, destination)) return true;
} return false;
} private int[] roll(int[][] maze, int row, int col, int rowInc, int colInc) {
while (canRoll(maze, row + rowInc, col + colInc)) {
row += rowInc;
col += colInc;
} return new int[]{row, col};
} private boolean canRoll(int[][] maze, int row, int col) {
if (row >= maze.length || row < 0 || col >= maze[0].length || col < 0) return false;
return maze[row][col] != 1; // 1 is a wall
}
}
Leetcode: The Maze(Unsolved locked problem)的更多相关文章
- Leetcode: Max Consecutive Ones II(unsolved locked problem)
Given a binary array, find the maximum number of consecutive 1s in this array if you can flip at mos ...
- Leetcode: The Maze III(Unsolved Lock Problem)
There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...
- [LeetCode] The Maze III 迷宫之三
There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...
- [LeetCode] The Maze II 迷宫之二
There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...
- [LeetCode] The Maze 迷宫
There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...
- Leetcode: The Maze II
There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...
- Leetcode 365. Water and Jug Problem
可以想象有一个无限大的水罐,如果我们有两个杯子x和y,那么原来的问题等价于是否可以通过往里面注入或倒出水从而剩下z. z =? m*x + n*y 如果等式成立,那么z%gcd(x,y) == 0. ...
- Leetcode: Find Permutation(Unsolve lock problem)
By now, you are given a secret signature consisting of character 'D' and 'I'. 'D' represents a decre ...
- Leetcode 笔记 117 - Populating Next Right Pointers in Each Node II
题目链接:Populating Next Right Pointers in Each Node II | LeetCode OJ Follow up for problem "Popula ...
随机推荐
- 必须知道的Linux内核常识详解
一.内核功能.内核发行版 1.到底什么是操作系统 (1)linux.windows.android.ucos就是操作系统: (2)操作系统本质上是一个程序,由很多个源文件构成,需要编译连接成操作系统程 ...
- js隐藏元素、jquery隐藏、css隐藏
$("#yh").css("display","none");//隐藏元素 $("#yh").css("dis ...
- Spark SQL大数据处理并写入Elasticsearch
SparkSQL(Spark用于处理结构化数据的模块) 通过SparkSQL导入的数据可以来自MySQL数据库.Json数据.Csv数据等,通过load这些数据可以对其做一系列计算 下面通过程序代码来 ...
- cmd应用基础 扫盲教程
cmd是什么? 对于程序员而言,cmd命令提示符是windows操作系统下一个比较重要的工具.对于程序员而言,为了追求更高的效率而抛弃花俏的界面已然是意见很常见的行为,截止到目前的,全世界仍有大量的服 ...
- Java笔记(二十) 注解
注解 一.内置注解 Java内置了一些常用注解: 1.@Override 该注解修饰一个方法,表示当前类重写了父类的该方法. 2.@Deprecated 该注解可以修饰类.方法.字段.参数等.表示对 ...
- 04-JQuery
今日任务 使用JQuery完成页面定时弹出广告 定时器: setInterval clearInterval setTimeout clearTimeout 显示: ...
- 有关svn的报错
由于目标计算机积极拒绝,无法连接.当报出这样的错的时候就是跨域的问题
- Array,prototype.concat.apply与[].conat.apply.
一直都知道JS数组Array内置对象有一个concat方法,但是也没怎么研究过,今天偶然就看了看 concat是连接一个或多个数组 返回的是连接后数组的一个副本 var oldArr=[]; var ...
- 前端性能优化 —— reflow(回流)和repaint(重绘)
简要:整个在浏览器的渲染过程中(页面初始化,用户行为改变界面样式,动画改变界面样式等)reflow(回流)和repaint(重绘) 会大大影响web性能,尤其是手机页面.因此我们在页面设计的时候要尽量 ...
- [Luogu P1495]曹冲养猪
题目链接 中国剩余定理(孙子定理)的裸题.直接放代码. #include<iostream> #include<cstdio> #include<algorithm> ...