773. Sliding Puzzle
Description
On an 2 x 3
board, there are five tiles labeled from 1
to 5
, and an empty square represented by 0
. A move consists of choosing 0
and a 4-directionally adjacent number and swapping it.
The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]]
.
Given the puzzle board board
, return the least number of moves required so that the state of the board is solved. If it is impossible for the state of the board to be solved, return -1
.
Example 1:
Input: board = [[1,2,3],[4,0,5]] Output: 1 Explanation: Swap the 0 and the 5 in one move.
Example 2:
Input: board = [[1,2,3],[5,4,0]] Output: -1 Explanation: No number of moves will make the board solved.
Example 3:
Input: board = [[4,1,2],[5,0,3]] Output: 5 Explanation: 5 is the smallest number of moves that solves the board. An example path: After move 0: [[4,1,2],[5,0,3]] After move 1: [[4,1,2],[0,5,3]] After move 2: [[0,1,2],[4,5,3]] After move 3: [[1,0,2],[4,5,3]] After move 4: [[1,2,0],[4,5,3]] After move 5: [[1,2,3],[4,5,0]]
Constraints:
board.length == 2
board[i].length == 3
0 <= board[i][j] <= 5
- Each value
board[i][j]
is unique.
Solutions
Solution: Breadth-First Search
- Time complexity: O((mn)!)
- Space complexity: O((mn)!)
JavaScript
js
/**
* @param {number[][]} board
* @return {number}
*/
const slidingPuzzle = function (board) {
const flexBoard = board.flat().join('');
const isSolved = board => board === '123450';
if (isSolved(flexBoard)) return 0;
const visited = new Set([flexBoard]);
const nextMoveMap = {
0: [1, 3],
1: [0, 2, 4],
2: [1, 5],
3: [0, 4],
4: [1, 3, 5],
5: [2, 4],
};
let queue = [{ index: flexBoard.indexOf('0'), current: flexBoard }];
let result = 0;
const swapTile = (from, to, current) => {
const nextBoard = current.split('');
[nextBoard[from], nextBoard[to]] = [nextBoard[to], nextBoard[from]];
const next = nextBoard.join('');
if (visited.has(next)) return null;
return next;
};
while (queue.length) {
const nextQueue = [];
result += 1;
for (const { index, current } of queue) {
for (const nextIndex of nextMoveMap[index]) {
const nextBoard = swapTile(index, nextIndex, current);
if (!nextBoard) continue;
if (isSolved(nextBoard)) return result;
visited.add(nextBoard);
nextQueue.push({ index: nextIndex, current: nextBoard });
}
}
queue = nextQueue;
}
return -1;
};