解答
java
class Solution {
static int V_RIGHT = 1;
static int V_LEFT = 2;
static int H_UP = 3;
static int H_DOWN = 4;
LinkedList<int[]> queue = new LinkedList<>();
Set<Integer> visited = new HashSet<>();
public int slidingPuzzle(int[][] board) {
int m = board.length;
int n = board[0].length;
int[] target = new int[] {1, 2, 3, 4, 5, 0};
int step = 0;
int[] init = new int[m * n];
for (int i = 0, pos = 0; i < m; ++i) {
for (int j = 0; j < n; ++j, ++pos) {
init[pos] = board[i][j];
}
}
queue.add(init);
visited.add(hash(init));
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; ++i) {
int[] status = queue.removeFirst();
if (equals(status, target)) {
return step;
}
int index = 0;
for (int j = 0; j < status.length; ++j) {
if (status[j] == 0) {
index = j;
break;
}
}
moveV(status, n, index, V_LEFT);
moveV(status, n, index, V_RIGHT);
moveH(status, n, index, H_UP);
moveH(status, n, index, H_DOWN);
}
++step;
}
return -1;
}
int hash(int[] status) {
int hashCode = 11;
for (int i = 0; i < status.length; ++i) {
hashCode = hashCode * 7 + status[i];
}
return hashCode;
}
boolean equals(int[] status, int[] target) {
for (int i = 0; i < status.length; ++i) {
if (status[i] != target[i]) {
return false;
}
}
return true;
}
void moveV(int[] status, int column, int index, int flag) {
int[] newStatus = Arrays.copyOf(status, status.length);
// 和右边交换。
if (flag == V_RIGHT) {
if (index % column + 1 < column) {
newStatus[index] = newStatus[index + 1];
newStatus[index + 1] = 0;
}
}
// 和左边交换
else if (flag == V_LEFT) {
if (index % column - 1 >= 0) {
newStatus[index] = newStatus[index - 1];
newStatus[index - 1] = 0;
}
}
int hashCode = hash(newStatus);
if (visited.add(hashCode)) {
queue.add(newStatus);
}
}
void moveH(int[] status, int column, int index, int flag) {
int[] newStatus = Arrays.copyOf(status, status.length);
if (flag == H_UP) {
if (index - column >= 0) {
newStatus[index] = newStatus[index - column];
newStatus[index - column] = 0;
}
} else if (flag == H_DOWN) {
if (index + column < status.length) {
newStatus[index] = newStatus[index + column];
newStatus[index + column] = 0;
}
}
int hashCode = hash(newStatus);
if (visited.add(hashCode)) {
queue.add(newStatus);
}
}
}
总结
基于广度优先算法求解。
要点:
- 将输入的多维数组转换为一维数组,计算指定位置的相邻节点。
- 去重的方法。