跳到主要内容

773.滑动谜题

链接:773.滑动谜题
难度:Hard
标签:广度优先搜索、数组、矩阵
简介:给出一个谜板的初始状态,返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。

题解 1 - typescript

  • 编辑时间:2021-06-26
  • 执行用时:192ms
  • 内存消耗:50.8MB
  • 编程语言:typescript
  • 解法介绍:广度悠闲搜索,计算每次移动后的最小步数。
function slidingPuzzle(board: number[][]): number {
const ANS_STR = '123,450';
const stringify = (board: (number | string)[][]) => board.map(v => v.join('')).join(',');
if (stringify(board) === ANS_STR) return 0;
const parse = (boardStr: string) => boardStr.split(',').map(v => v.split(''));
const getZeroIndex = (index: number): [number, number] =>
index <= 2 ? [0, index] : [1, index - 4];
const queue: string[] = [stringify(board)];
const map = new Map<string, number>([[queue[0], 0]]);
let ans = Infinity;
const updateMap = (newStr: string, step: number) => {
if (newStr === ANS_STR) ans = Math.min(ans, step + 1);
else {
map.has(newStr) || queue.push(newStr);
map.set(newStr, Math.min(map.get(newStr) ?? Infinity, step + 1));
}
};
const swap = (board: string[][], row1: number, col1: number, row2: number, col2: number) => {
[board[row1][col1], board[row2][col2]] = [board[row2][col2], board[row1][col1]];
};
while (queue.length !== 0) {
const boardStr = queue.shift()!;
const step = map.get(boardStr)!;
const [row, col] = getZeroIndex(boardStr.indexOf('0'));
const board = parse(boardStr);
if (row === 0) {
swap(board, row, col, row + 1, col);
updateMap(stringify(board), step);
swap(board, row, col, row + 1, col);
}
if (row === 1) {
swap(board, row, col, row - 1, col);
updateMap(stringify(board), step);
swap(board, row, col, row - 1, col);
}
if (col > 0) {
swap(board, row, col, row, col - 1);
updateMap(stringify(board), step);
swap(board, row, col, row, col - 1);
}
if (col < 2) {
swap(board, row, col, row, col + 1);
updateMap(stringify(board), step);
swap(board, row, col, row, col + 1);
}
}
return ans === Infinity ? -1 : ans;
}