https://jixiangsanbao.wordpress.com/2015/01/12/shortest-distance-in-a-2d-map/
Given a 2D map find the shortest distance from the starting point to the finish
* point. You can only move horizontally or vertically. You cannot leave the
* boundaries of the map.
* Open spaces are represented by .
* Walls are represented by x
* Points are represented as (row, col) where (0,0) is top left corner
We can use a bfs to solve this problem.
public enum State {
unvisited, visited, visiting; // no need to use visiting
}
public static class Node {
int x;
int y;
public Node(int x, int y){
this.x = x;
this.y = y;
}
}
public static int bfs(char[][] g, Node start, Node end){
int m = g.length;
int n = g[0].length;
State[][] visit = new State[m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
visit[i][j] = State.unvisited;
}
}
int[][] distance = new int[m][n];
Queue<Node> queue = new LinkedList<Node>();
queue.add(start);
visit[start.x][start.y] = State.visiting;
distance[start.x][start.y] = 0;
while(!queue.isEmpty()){
Node curr = queue.poll();
int curr_x = curr.x;
int curr_y = curr.y;
for(Node node : getAdjacent(g, curr, visit)){
int node_x = node.x;
int node_y = node.y;
if(visit[node_x][node_y] == State.unvisited){
if(node_x == end.x && node_y == end.y){
return distance[curr_x][curr_y]+1;
}
else{
visit[node_x][node_y] = State.visiting;
distance[node_x][node_y] = distance[curr_x][curr_y]+1;
queue.add(new Node(node_x, node_y));
}
}
}
visit[curr_x][curr_y] = State.visited;
}
return -1;
}
//get all adjacent nodes of Node n
public static ArrayList<Node> getAdjacent(char[][] g, Node n, State[][] visit) {
int x = n.x;
int y = n.y;
ArrayList<Node> res = new ArrayList<Node>();
//up
if(isValid(g,x-1,y,visit)){
res.add(new Node(x-1,y));
}
//left
if(isValid(g,x,y-1,visit)){
res.add(new Node(x,y-1));
}
//right
if(isValid(g,x,y+1,visit)){
res.add(new Node(x,y+1));
}
//down
if(isValid(g,x+1,y,visit)){
res.add(new Node(x+1,y));
}
return res;
}
public static boolean isValid(char[][] g, int x, int y, State[][] visit){
if(x < 0 || x >= g.length || y < 0 || y >= g[0].length || visit[x][y] != State.unvisited || g[x][y] != '.'){
return false;
}
return true;
}
Given a 2D map find the shortest distance from the starting point to the finish
* point. You can only move horizontally or vertically. You cannot leave the
* boundaries of the map.
* Open spaces are represented by .
* Walls are represented by x
* Points are represented as (row, col) where (0,0) is top left corner
We can use a bfs to solve this problem.
public enum State {
unvisited, visited, visiting; // no need to use visiting
}
public static class Node {
int x;
int y;
public Node(int x, int y){
this.x = x;
this.y = y;
}
}
public static int bfs(char[][] g, Node start, Node end){
int m = g.length;
int n = g[0].length;
State[][] visit = new State[m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
visit[i][j] = State.unvisited;
}
}
int[][] distance = new int[m][n];
Queue<Node> queue = new LinkedList<Node>();
queue.add(start);
visit[start.x][start.y] = State.visiting;
distance[start.x][start.y] = 0;
while(!queue.isEmpty()){
Node curr = queue.poll();
int curr_x = curr.x;
int curr_y = curr.y;
for(Node node : getAdjacent(g, curr, visit)){
int node_x = node.x;
int node_y = node.y;
if(visit[node_x][node_y] == State.unvisited){
if(node_x == end.x && node_y == end.y){
return distance[curr_x][curr_y]+1;
}
else{
visit[node_x][node_y] = State.visiting;
distance[node_x][node_y] = distance[curr_x][curr_y]+1;
queue.add(new Node(node_x, node_y));
}
}
}
visit[curr_x][curr_y] = State.visited;
}
return -1;
}
//get all adjacent nodes of Node n
public static ArrayList<Node> getAdjacent(char[][] g, Node n, State[][] visit) {
int x = n.x;
int y = n.y;
ArrayList<Node> res = new ArrayList<Node>();
//up
if(isValid(g,x-1,y,visit)){
res.add(new Node(x-1,y));
}
//left
if(isValid(g,x,y-1,visit)){
res.add(new Node(x,y-1));
}
//right
if(isValid(g,x,y+1,visit)){
res.add(new Node(x,y+1));
}
//down
if(isValid(g,x+1,y,visit)){
res.add(new Node(x+1,y));
}
return res;
}
public static boolean isValid(char[][] g, int x, int y, State[][] visit){
if(x < 0 || x >= g.length || y < 0 || y >= g[0].length || visit[x][y] != State.unvisited || g[x][y] != '.'){
return false;
}
return true;
}