Я пытался найти кратчайший путь скольжения между двоичными ячейками (0 или 1) в двоичной сетке / матрице. Это немного отличается от кратчайшего пути в соседней матрице (вверх, вниз, влево, вправо). Я использую BFS, чтобы найти кратчайший путь в соседней матрице. Точно так же я думаю, что могу скользить в макс. Смежных направлениях, посещать одновременно или посещать после макс. Смежного слайда, но ни один из них не кажется правильным. Если я пытаюсь скользить в максимально соседнем направлении, то у меня нет кратчайшего пути скольжения. Как еще я могу подойти к этому?
import java.util.LinkedList;
public class ShortestSlidingPathBetweenCellsBFS {
static final int BINARY_BLOCK = 1;
private static class Cell {
int x;
int y;
int dist; //distance
Cell prev; //parent / last visited cell in the path
Cell(int x, int y, int dist, Cell prev) {
this.x = x;
this.y = y;
this.dist = dist;
this.prev = prev;
}
@Override
public String toString(){
return "(" + x + "," + y + ")";
}
}
//BFS, Time O(n^2), Space O(n^2)
public static void shortestPath(int[][] matrix, int[] start, int[] end) {
int sx = start[0], sy = start[1];
int dx = end[0], dy = end[1];
//if start or end value is 0, return
if (matrix[sx][sy] == BINARY_BLOCK || matrix[dx][dy] == BINARY_BLOCK)
return;
int m = matrix.length;
int n = matrix[0].length;
Cell[][] cells = new Cell[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] != BINARY_BLOCK) { // if cell can be visited
cells[i][j] = new Cell(i, j, Integer.MAX_VALUE, null); // init cell element with default Cell
}
}
}
LinkedList<Cell> queue = new LinkedList<>();
Cell src = cells[sx][sy];
src.dist = 0;
queue.add(src);
Cell dest = null;
Cell present; // present cell
// while queue
while ((present = queue.poll()) != null) {
//find destination
if (present.x == dx && present.y == dy) {
dest = present;
break;
}
while (present.x != BINARY_BLOCK) {
present.x -= 1;
}
visit(cells, queue, present.x, present.y, present);
// moving down
while (present.x != BINARY_BLOCK) {
present.x += 1;
}
visit(cells, queue, present.x, present.y, present);
// moving left
while (present.y != BINARY_BLOCK) {
present.y -= 1;
}
visit(cells, queue, present.x, present.y, present);
//moving right
while (present.y != BINARY_BLOCK) {
present.y += 1;
}
}
if (dest == null) {
return;
} else { // print out shortest path
LinkedList<Cell> path = new LinkedList<>();
present = dest;
do {
path.addFirst(present);
} while ((present = present.prev) != null);
System.out.println(path);
}
}
//function to update cell visiting status
static void visit(Cell[][] cells, LinkedList<Cell> queue, int x, int y, Cell parent) {
if (x < 0 || x >= cells.length || y < 0 || y >= cells[0].length || cells[x][y] == null) {
return;
}
int dist = parent.dist + 1;
Cell present = cells[x][y];
if (dist < present.dist) {
present.dist = dist;
present.prev = parent;
queue.add(present);
}
}
public static void main(String[] args) {
int[][] matrix1 = {
{0, 0, 1, 0},
{1, 0, 0, 0},
{0, 0, 0, 0},
{1, 1, 0, 0}
};
int[] start1 = {1, 1};
int[] end1 = {3, 3};
shortestPath(matrix1, start1, end1);
int[][] matrix2 = {
{0, 0, 1, 0},
{1, 0, 1, 0},
{0, 0, 0, 0},
{1, 1, 0, 0}
};
int[] start2 = {1, 1};
int[] end2 = {3, 3};
shortestPath(matrix2, start2, end2);
}
}