@(labuladong的算法小抄)[BFS]
leetcode 773. 滑动谜题
题目描述
解题思路
参考:labuladong的算法小抄P310
class Solution {
/* 2*3的原始数组中,每个元素的相邻元素的下标 */
/* 例如neighbor[5]={2, 4}表示board中第6个数组的邻居元素分别是第3和第5个元素 */
int[][] neighbor = new int[][]{
{1, 3},
{0, 2, 4},
{1, 5},
{0, 4},
{1, 3, 5},
{2, 4}
};
public int slidingPuzzle(int[][] board) {
/* 将board展平为一维,存入start作为初始状态 */
String start = "";
/* 最终要凑出的目标 */
String target = "123450";
/* 初始化start */
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
start += (char) (board[i][j] + '0');
}
}
/* BFS框架 */
Queue<String> q = new LinkedList<>();
Set<String> visited = new HashSet<>();
q.offer(start);
visited.add(start);
/* 移动的步数 */
int step = 0;
while (!q.isEmpty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
String cur = q.poll();
/* 到达终点,返回步数 */
if (cur.equals(target)) {
return step;
}
/* 找到数字0的下标 */
int zeroIdx = cur.indexOf('0');
/* 遍历数字0的所有邻居的下标 */
for (int idx : neighbor[zeroIdx]) {
/* 交换数字0和当前邻居元素的下标,生成新的拼图 */
String newBoard = exchangeIdxOfString(cur, zeroIdx, idx);
/* 防止重复访问 */
if (!visited.contains(newBoard)) {
q.offer(newBoard);
visited.add(newBoard);
}
}
}
/* 遍历完当前层后,步数加1 */
step++;
}
return -1;
}
/* 交换str中下标分别为src和dist的字符 */
private String exchangeIdxOfString(String str, int src, int dist) {
char[] tmpStr = str.toCharArray();
char tmpCh = tmpStr[src];
tmpStr[src] = tmpStr[dist];
tmpStr[dist] = tmpCh;
return new String(tmpStr);
}
}