-
Notifications
You must be signed in to change notification settings - Fork 857
Expand file tree
/
Copy pathProblem2.java
More file actions
124 lines (97 loc) · 4.11 KB
/
Problem2.java
File metadata and controls
124 lines (97 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Time Complexity : O(k mn) where k is the number of 1s in the matrix and m,n are the dimenstions of the matrix.
// Space Complexity : O(mn)
// Did this code successfully run on Leetcode : yes
// Any problem you faced while coding this : no
// Your code here along with comments explaining your approach
/**
* Using level order traversal to start navigating the maze from starting position in all directions.
* Keep going in one direction till either we see 1 or the end of the maze. Go 1 step back since that will be the ball's stopping point.
* Mark the stopping point with 2 so we know that it has been visited and add the current position to queue for further maze traversal.
* If we find the ball's stopping point to be destination at any point, we return true.
* We return false at the end since we traversed through all possible stopping points and the ball never stopped at the destination.
*/
class BFSSolution {
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
int m = maze.length;
int n = maze[0].length;
if (m == 0 || n == 0) {
return false;
}
if (start[0] == destination[0] && start[1] == destination[1])
return true;
// Using queue for level order traversal
Queue<int[]> q = new LinkedList<>();
q.add(start);
// marking it with 2 to consider it as visited
maze[start[0]][start[1]] = 2;
int[][] dirs = new int[][]{{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
while (!q.isEmpty()) {
int[] curr = q.poll();
for (int[] dir : dirs) {
// move one step to get the next element in current directionb
int r = curr[0] + dir[0];
int c = curr[1] + dir[1];
// keep going in this direction till end of maze or 1 is received
while (r >= 0 && r < m && c >= 0 && c < n && maze[r][c] != 1) {
r += dir[0];
c += dir[1];
}
// go one step back since this will be the stopping point
r -= dir[0];
c -= dir[1];
// found the destination as stopping point
if (r == destination[0] && c == destination[1])
return true;
// if this position was never a stopping point for the ball, add it to queue and mark it with visited
if (maze[r][c] != 2) {
maze[r][c] = 2;
q.add(new int[]{r, c});
}
}
}
return false;
}
}
class DFSSolution {
int m;
int n;
int[][] dirs = new int[][]{{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
this.m = maze.length;
this.n = maze[0].length;
if (m == 0 || n == 0) {
return false;
}
if (start[0] == destination[0] && start[1] == destination[1])
return true;
return dfs(maze, start[0], start[1], destination);
}
private boolean dfs(int[][] maze, int i, int j, int[] destination) {
// stopped at the destination
if (i == destination[0] && j == destination[1])
return true;
// already visited this node and it wasn't the destination
if (maze[i][j] == 2)
return false;
// marking it as visited
maze[i][j] = 2;
for (int[] dir : dirs) {
// starting from the neighbor of the current element
int r = i + dir[0];
int c = j + dir[1];
// keep going in this direction till end of maze or 1 is received
while (r >= 0 && r < m && c >= 0 && c < n && maze[r][c] != 1) {
r += dir[0];
c += dir[1];
}
// go one step back since this will be the stopping point
r -= dir[0];
c -= dir[1];
// call the function recursively and bubble the match up
if (dfs(maze, r, c, destination))
return true;
}
// no match found
return false;
}
}