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 ...
随机推荐
- Python与R的区别和联系
转自:http://bbs.pinggu.org/thread-3078817-1-1.html 有人说Python和R的区别是显而易见的,因为R是针对统计的,python是给程序员设计的,其实这话对 ...
- ELK对Tomcat日志双管齐下-告警触发/Kibana日志展示
今天我们来聊一聊Tomcat,相信大家并不陌生,tomcat是一个免费开源的web应用服务器,属于轻量级的应用程序,在小型生产环境和并发不是很高的场景下被普遍使用,同时也是开发测试JSP程序的首选.也 ...
- 咸鱼入门到放弃5--Session和Cookie
保存会话数据的两种技术 1.Cookie Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器.当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去. ...
- linux 添加ssh和开启ssh服务apt管理的ubuntu
是在ubuntu下出现的需求 现笔记记录 apt-get update 更新源命令 apt-get install openssh-server 安装ssh服务 容易出现无法定位软件包.出现此问 ...
- easyui commobox省市区县三级联动
1.前端代码 <div class="col-6 f-group"> <label class="col-4 left_red"> 省名 ...
- JavaScript浏览器解析原理
首先,JavaScript的特点是: 1. 跨平台 可以再不同的操作系统上运行. 2. 弱类型 与之相对的是强类型 强类型:在定义变量的时候,需要将变量的数据类型表明.例如:Java 弱类型:定义变量 ...
- 07_ for 练习 _ sumOfOdd
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- mobile_5 种常见适配_设备兼容
em 参照本身元素的 font-size rem 参照 html 根元素 的 font-size 1. rem 适配 (同一元素,在不同设备上,效果一样) 适用情况: 当页面大于 独立像素375 ...
- mysql having和where的区别
having子句与where子句一样,都是用于条件判断的. 区别1 where是判断数据从磁盘读入内存的时候 having是判断分组统计之前的所有条件 区别原理 区别2 having子句中可以使用字段 ...
- asch相关的linux基础知识分享
本文针对的人群:会用putty.SecureCRT.xhsell等工具ssh连接到自己的asch服务器上,但不怎么会执行命令的人.高手请绕路~ 本文主要围绕受托人搭建.维护涉及相关的内容进行Linux ...
Example 2
Input 1: a maze represented by a 2D array
0 0 1 0 0
Note: