Skip to content

Commit 63c8cb6

Browse files
[LEET-490] add 490
1 parent e1f0400 commit 63c8cb6

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed

leetcode-algorithms/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
|500|[Keyboard Row](https://leetcode.com/problems/keyboard-row/)|[Solution](../../master/leetcode-algorithms/src/main/java/com/stevesun/solutions/KeyboardRow.java) | O(n) |O(1) | Easy|
1212
|494|[Target Sum](https://leetcode.com/problems/target-sum/)|[Solution](../../master/leetcode-algorithms/src/main/java/com/stevesun/solutions/TargetSum.java) | O(2^n) |O(1) | Medium|
1313
|492|[Construct the Rectangle](https://leetcode.com/problems/construct-the-rectangle/)|[Solution](../../master/leetcode-algorithms/src/main/java/com/stevesun/solutions/ConstructTheRectangle.java) | O(n) |O(1) | Easy| Array
14+
|490|[The Maze](https://leetcode.com/problems/the-maze/)|[Solution](../../master/leetcode-algorithms/src/main/java/com/stevesun/solutions/TheMaze.java) | O(m*n) |O(m*n) | Medium| BFS
1415
|485|[Max Consecutive Ones](https://leetcode.com/problems/max-consecutive-ones/)|[Solution](../../master/leetcode-algorithms/src/main/java/com/stevesun/solutions/MaxConsecutiveOnes.java) | O(n) |O(1) | Easy| Array
1516
|482|[License Key Formatting](https://leetcode.com/problems/license-key-formatting/)|[Solution](../../master/leetcode-algorithms/src/main/java/com/stevesun/solutions/LicenseKeyFormatting.java) | O(n) |O(n) | Medium|
1617
|477|[Total Hamming Distance](https://leetcode.com/problems/total-hamming-distance/)|[Solution](../../master/leetcode-algorithms/src/main/java/com/stevesun/solutions/TotalHammingDistance.java) | O(n) |O(1) | Medium| Bit Manipulation
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.stevesun;
2+
3+
import com.stevesun.solutions.TheMaze;
4+
import org.junit.Before;
5+
import org.junit.BeforeClass;
6+
import org.junit.Test;
7+
8+
import static junit.framework.Assert.assertEquals;
9+
10+
public class TheMazeTest {
11+
private static TheMaze test;
12+
private static boolean expected;
13+
private static boolean actual;
14+
private static int[][] maze;
15+
private static int[] start;
16+
private static int[] destination;
17+
18+
@BeforeClass
19+
public static void setup(){
20+
test = new TheMaze();
21+
}
22+
23+
@Before
24+
public void setupForEachTest(){}
25+
26+
@Test
27+
public void test1(){
28+
maze = new int[][]{
29+
{0,0,0,0,0},
30+
{1,1,0,0,1},
31+
{0,0,0,0,0},
32+
{0,1,0,0,1},
33+
{0,1,0,0,0}
34+
};
35+
start = new int[]{4,3};
36+
destination = new int[]{0,1};
37+
actual = test.hasPath(maze, start, destination);
38+
expected = false;
39+
assertEquals(expected, actual);
40+
41+
}
42+
43+
@Test
44+
public void test2(){
45+
maze = new int[][]{
46+
{0,0,1,0,0},
47+
{0,0,0,0,0},
48+
{0,0,0,1,0},
49+
{1,1,0,1,1},
50+
{0,0,0,0,0}
51+
};
52+
start = new int[]{0,4};
53+
destination = new int[]{4,4};
54+
actual = test.hasPath(maze, start, destination);
55+
expected = true;
56+
assertEquals(expected, actual);
57+
}
58+
}

0 commit comments

Comments
 (0)