1
+ package com .stevesun .solutions ;
2
+
3
+ import java .util .LinkedList ;
4
+ import java .util .Queue ;
5
+
6
+ /**
7
+ * 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.
8
+
9
+ Given the ball's start position, the destination and the maze, determine whether the ball could stop at the destination.
10
+
11
+ 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.
12
+
13
+ Example 1
14
+
15
+ Input 1: a maze represented by a 2D array
16
+
17
+ 0 0 1 0 0
18
+ 0 0 0 0 0
19
+ 0 0 0 1 0
20
+ 1 1 0 1 1
21
+ 0 0 0 0 0
22
+
23
+ Input 2: start coordinate (rowStart, colStart) = (0, 4)
24
+ Input 3: destination coordinate (rowDest, colDest) = (4, 4)
25
+
26
+ Output: true
27
+ Explanation: One possible way is : left -> down -> left -> down -> right -> down -> right.
28
+
29
+ Example 2
30
+
31
+ Input 1: a maze represented by a 2D array
32
+
33
+ 0 0 1 0 0
34
+ 0 0 0 0 0
35
+ 0 0 0 1 0
36
+ 1 1 0 1 1
37
+ 0 0 0 0 0
38
+
39
+ Input 2: start coordinate (rowStart, colStart) = (0, 4)
40
+ Input 3: destination coordinate (rowDest, colDest) = (3, 2)
41
+
42
+ Output: false
43
+ Explanation: There is no way for the ball to stop at the destination.
44
+
45
+ Note:
46
+ There is only one ball and one destination in the maze.
47
+ Both the ball and the destination exist on an empty space, and they will not be at the same position initially.
48
+ 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.
49
+ The maze contains at least 2 empty spaces, and both the width and height of the maze won't exceed 100.
50
+ */
51
+ public class TheMaze {
52
+ /**
53
+ * BFS: the key part of this algorithm is that: this is a ball that won't stop rolling until it hits a wall.
54
+ * This means we'll have to store all the empty spaces where the ball was forced to stop into the queue, these are
55
+ * the only places where the next starting points could be.
56
+ * Then we use BFS to traverse through all four directions of each starting point.
57
+
58
+ * Also, another point to note is: it must be a stop point for the ball.
59
+ */
60
+ public boolean hasPath (int [][] maze , int [] start , int [] destination ) {
61
+ if (start [0 ] == destination [0 ] && destination [0 ] == destination [1 ]) return true ;
62
+ final int [] directions = new int []{-1 , 0 , 1 , 0 , -1 };
63
+ Queue <Point > queue = new LinkedList <>();
64
+ queue .offer (new Point (start [0 ], start [1 ]));
65
+ int m = maze .length , n = maze [0 ].length ;
66
+ boolean [][] visited = new boolean [m ][n ];
67
+ visited [start [0 ]][start [1 ]] = true ;
68
+
69
+ while (!queue .isEmpty ()) {
70
+ Point curr = queue .poll ();
71
+ int x = curr .x , y = curr .y ;//keep the original value
72
+ for (int i = 0 ; i < directions .length - 1 ; i ++) {
73
+ int xx = x , yy = y ;//use temp variables to move
74
+ while (xx >= 0 && yy >= 0 && xx < m && yy < n && maze [xx ][yy ] == 0 ) {
75
+ xx += directions [i ];
76
+ yy += directions [i + 1 ];
77
+ }
78
+ xx -= directions [i ];
79
+ yy -= directions [i + 1 ];
80
+ if (visited [xx ][yy ]) continue ;
81
+ visited [xx ][yy ] = true ;
82
+ if (destination [0 ] == xx && destination [1 ] == yy ) return true ;
83
+ queue .offer (new Point (xx , yy ));
84
+ }
85
+ }
86
+ return false ;
87
+ }
88
+
89
+ class Point {
90
+ int x ;
91
+ int y ;
92
+
93
+ public Point (int x , int y ) {
94
+ this .x = x ;
95
+ this .y = y ;
96
+ }
97
+ }
98
+ }
0 commit comments