# Shortest Path in a Binary Maze in Java

In the input, there is a MxN matrix with elements that may either be 0 or 1. The shortest route between a given source cell and a destination address cell must be found. A cell may only be used to make the route if its value is 1.

Example:

Input: mat[ROW][COL] = {{1,0,1,1,1},

{1,0,1,0,1},

{1,1,1,0,1},

{0,0,0,0,1},

{1,1,1,0,1}};

The source cell is (0,0) and the destination cell is (4,4).

Output: Shortest Path: 12

## Approach: Using Depth-first search (DFS)

The maze is assumed to have walls represented by the value 1, and open spaces represented by the value 0. The algorithm starts at the top-left corner of the maze and explores all possible paths through the maze using recursion until it reaches the bottom-right corner. It keeps track of the length of the path found so far and updates the minimum path length when it reaches the destination. If no path is found, it returns -1.

Filename: ShortestPathDFS.java

Output:

```Shortest Path using DFS: 12
```

Explanation: The given Java program implements the Depth First Search (DFS) algorithm to find the shortest path in a maze represented by a 2D array of integers. The program takes the maze as input and initializes a boolean array to keep track of visited cells. It starts exploring the maze from the top-left cell (0,0) and recursively traverses all possible paths until it reaches the bottom-right cell (maze.length-1, maze[0].length-1) or a dead end. During traversal, the program increments the distance by 1 for each visited cell and updates the shortestPath variable if it finds a shorter path to the destination cell. Finally, it returns the shortestPath value or 0 if no path exists. The program also contains a main method to demonstrate the functionality of the findShortestPath method by passing the given input maze and printing the shortest path using DFS.

Complexity Analysis: The time complexity of this implementation is O(m * n), where m is the number of rows and n is the number of columns in the input maze. The reason for this is that, in the DFS algorithm, each cell in the maze is visited at most once.

The space complexity is also O(m * n), due to the boolean visited array that is created to keep track of visited cells. Additionally, the recursive nature of the DFS algorithm can lead to a large stack space usage in the worst case. However, since the maze in this implementation is relatively small, this is not a significant concern.

Overall, this implementation is simple and easy to understand, but it may not be the most efficient for larger mazes. Other algorithms, such as Dijkstra's algorithm or A* search, may provide better performance for larger and more complex mazes.

## Approach: Using Dijkstra's algorithm

Filename: BinaryMazeShortestPath.java

Output:

```Shortest path length: 12
```

Explanation: The above code implements Dijkstra's algorithm to find the shortest path between two points in a maze. The maze is represented as a 2D array where 1s represent paths and 0s represent walls. The algorithm uses a priority queue to select the unvisited cell with the minimum distance from the source cell.

The shortestPath function takes the maze, start coordinates (startX and startY) and end coordinates (endX and endY) as input and returns the shortest path length between the start and end points.

The function initializes the dist array to infinity for all cells except the start cell, which is set to 0. It also initializes a visited array to keep track of visited cells.

The algorithm then starts by adding the start cell to the priority queue with distance 0. It continues to loop until the priority queue is empty or the end cell is reached. In each iteration, the cell with the smallest distance is selected from the queue and its neighbors are explored. The distance of each neighbor is updated if a shorter path is found and the neighbor is added to the priority queue.

The method returns -1 if the end cell cannot be reached or the shortest path length if the end cell is reached.

The main method creates a maze and calls the shortestPath function with the start and end coordinates. The length of the shortest path is printed to the console.

Complexity Analysis: The time complexity of the Dijkstra's algorithm implementation in the given code is O(N^2 log N), where N is the number of nodes (or cells) in the input grid. The reason for this is that we use a priority queue to process the adjacent nodes of each node in the grid, taking at most O(log N) time per insertion or removal, and we ensure that each node is processed only once. In the worst case, all nodes are visited, and therefore the overall time complexity is O(N^2 log N). The space complexity is also O(N^2) because the algorithm stores the distance and visited status of each node in two separate N x N arrays.

## Approach: Using Breadth-First Search Algorithm

Breadth-First Search (BFS) is one of the most common algorithms used to find the shortest path in a binary maze. It works by exploring all the neighbors of a cell before moving on to their neighbors.

Filename: ShortestPathBinaryMaze.java

Output:

```Shortest path length: 12
```

Explanation: The above Java code implements the breadth-first search (BFS) algorithm to find the shortest path in a binary maze from a source point to a destination point. The code defines a nested class Point to store the coordinates of a matrix cell, and uses a 2D integer array to represent the maze where 1's indicate valid cells and 0's indicate blocked cells. The isValid function checks if a cell is within the maze bounds and is a valid cell to traverse. The shortestPathBFS function uses a queue to perform BFS on the maze, starting from the source point and stopping when the destination point is reached. The distance of each cell from the source is stored in a 2D integer array dist, and the function returns the distance of the destination point from the source, or -1 if the destination point cannot be reached.

### Complexity Analysis

Time Complexity Analysis: The time complexity of the BFS algorithm is O(V+E), where V is the number of vertices and E is the number of edges. In this case, the number of vertices is equal to the number of cells in the matrix, which is rows x cols. The number of edges in the worst case can be considered as O(V), since each cell can have at most 4 edges (up, down, left, right) and in the worst case, all cells are connected to each other. Therefore, the time complexity of the algorithm is O(rows x cols), since V = rows x cols and E = O(V).

Space Complexity Analysis: The space complexity of the algorithm is O(V), where V is the number of vertices, i.e., rows x cols. The reason for this is that we keep track of the distance of each cell from the source by maintaining a distance matrix with dimensions of rows by cols. Additionally, we are using a queue to store the cells to be visited, which can have at most V elements in the worst case.

Overall, the time complexity of the algorithm is O(rows x cols) and the space complexity is O(rows x cols).

## Approach: Using Backtracking

Backtracking algorithms work by recursively exploring the search space, marking each candidate solution as either a success or a failure, and then undoing each choice until a valid solution is found or all possibilities have been exhausted.

### Implementation:

Filename: ShortestPathBacktracking.java

Output:

```Shortest Path: 12
```

Explanation: The ShortestPathBacktracking class contains a recursive method named findShortestPath that uses backtracking to find the shortest path in a maze from the starting point (0,0) to the end point (rows-1,cols-1). The maze is represented by a two-dimensional array of integers where 1 represents a valid path and 0 represents a wall. The algorithm uses a Boolean array called visited to keep track of the visited cells.

The findShortestPath method takes as input the maze, visited array, current row and column, end row and column, current distance, and an array to store the shortest path found so far. It first checks if the current cell is valid and not visited. If it is the end cell, it updates the shortest path if the current distance is less than the shortest path found so far. Then it sets the current cell as visited and recursively calls itself for the four possible moves: down, up, right, and left. After each recursive call, it unsets the visited flag of the current cell to allow it to be visited again in a different path.

The main method initializes the maze and calls the findShortestPath method, printing the result.

Complexity Analysis: The time complexity of this algorithm is O(4^(nm)) in the worst case, where n is the number of rows and m is the number of columns in the maze. By exploring each of the four possible directions for every cell, we use a recursive depth-first search to navigate through the maze until we arrive at the destination cell. In the worst case, we may need to explore all possible paths in the maze, which would give us a total of 4^(nm) possible paths to consider.

The space complexity of this algorithm is O(nm), where n is the number of rows and m is the number of columns in the maze. A boolean matrix is used to keep track of visited cells, and it has the same dimensions as the maze.Additionally, we use a recursive function that may call itself up to nm times, which could result in a maximum call stack depth of n*m.