The problem is a binary maze where 1's are walls and 0's are valid paths. You start from the top left (0,0) and you have to reach the bottom right (width -1, height -1). You have to find the shortest path from the top left to the bottom right. The twist comes in because you are allowed to remove one wall at most and this is the part that is confusing me. My current code can solve the shortest path without calculating for a wall being removed.
Here are a couple of examples: [0,1,1,0], [0,0,0,1], [1,1,0,0], [1,1,1,0] Answer: 7 moves (including entrance and exit)
Example 2: [0,0,0,0,0],[0,1,1,1,0],[1,0,0,0,0],[0,1,1,1,1],[0,1,1,1,1],[0,0,0,0,0] Answer: 11 (Because you can break the wall at position [0][1] to make the path shorter)
So like I said before my code will find the shortest path, but at the moment doesn't try to remove a wall for a shorter path, mostly because I dont understand how to. I was thinking that I remove one wall at a time and continually re-run to see if a shorter path is produced but this seems very costly operation, but it might get the job done. However, I was hoping that I could find a more clear and easier way to do so.
import java.util.*;
public class Maze {
public static void main(String [] args)
{
int[][] arr = new int[][] {
{0,0,0,0,0},
{1,1,1,1,0},
{0,0,0,0,0},
{0,1,1,1,1},
{0,1,1,1,1},
{0,0,0,0,0},
};
answer(arr);
}
public static int answer(int[][] maze) {
maze[maze.length-1][maze[0].length -1] = 9;
Point p = getPathBFS(0,0,maze);
int length = 1;
while(p.getParent() != null) {
p = p.getParent();
length++;
}
System.out.println(length);
return length;
}
private static class Point {
int x;
int y;
Point parent;
public Point(int x, int y, Point parent) {
this.x = x;
this.y = y;
this.parent = parent;
}
public Point getParent() {
return this.parent;
}
}
public static Queue<Point> q = new LinkedList<Point>();
public static Point getPathBFS(int x, int y,int[][] arr) {
q.add(new Point(x,y, null));
while(!q.isEmpty()) {
Point p = q.remove();
if (arr[p.x][p.y] == 9) {
return p;
}
if(isFree(p.x+1,p.y,arr)) {
arr[p.x][p.y] = -1;
Point nextP = new Point(p.x+1,p.y, p);
q.add(nextP);
}
if(isFree(p.x-1,p.y,arr)) {
arr[p.x][p.y] = -1;
Point nextP = new Point(p.x-1,p.y, p);
q.add(nextP);
}
if(isFree(p.x,p.y+1,arr)) {
arr[p.x][p.y] = -1;
Point nextP = new Point(p.x,p.y+1, p);
q.add(nextP);
}
if(isFree(p.x,p.y-1,arr)) {
arr[p.x][p.y] = -1;
Point nextP = new Point(p.x,p.y-1, p);
q.add(nextP);
}
}
return null;
}
public static boolean isFree(int x, int y,int[][] arr) {
if((x >= 0 && x < arr.length) && (y >= 0 && y < arr[x].length) && (arr[x][y] == 0 || arr[x][y] == 9)) {
return true;
}
return false;
}
}