Problem
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.
Solution (Java)
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
public class Solution {
private static class Node {
public String board;
public int depth;
public int y;
public int x;
public Node(String board, int depth, int y, int x) {
this.board = board;
this.depth = depth;
this.y = y;
this.x = x;
}
}
public int slidingPuzzle(int[][] board) {
String targetStr = "123450";
StringBuilder sb = new StringBuilder();
int y = 0;
int x = 0;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == 0) {
y = i;
x = j;
}
sb.append(board[i][j]);
}
}
Set<String> seen = new HashSet<>();
Queue<Node> q = new LinkedList<>();
q.add(new Node(sb.toString(), 0, y, x));
int[][] dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
while (!q.isEmpty()) {
Node next = q.poll();
String s = next.board;
if (!seen.contains(s)) {
if (s.equals(targetStr)) {
return next.depth;
}
int nextDepth = next.depth + 1;
y = next.y;
x = next.x;
for (int[] vector : dir) {
int nextY = y + vector[0];
int nextX = x + vector[1];
if (0 <= nextY
&& nextY < board.length
&& 0 <= nextX
&& nextX < board[0].length) {
String newBoard = swap(s, y, x, nextY, nextX);
q.add(new Node(newBoard, nextDepth, nextY, nextX));
}
}
seen.add(s);
}
}
return -1;
}
public String swap(String board, int y1, int x1, int y2, int x2) {
char[] arr = board.toCharArray();
char t = board.charAt(y1 * 3 + x1);
arr[y1 * 3 + x1] = board.charAt(y2 * 3 + x2);
arr[y2 * 3 + x2] = t;
return new String(arr);
}
}
Solution (C++)
class Solution {
public:
int slidingPuzzle(vector<vector<int>>& board) {
constexpr int kRows = 2;
constexpr int kCols = 3;
string goal;
string start;
for (int i = 0; i < board.size(); ++i)
for (int j = 0; j < board[0].size(); ++j) {
start += (board[i][j] + '0');
goal += (i * kCols + j + 1) % (kRows * kCols) + '0'; // 12345...0
}
if (start == goal) return 0;
constexpr int dirs[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
set<string> visited{start};
int steps = 0;
queue<string> q;
q.push(start);
while (!q.empty()) {
++steps;
int size = q.size();
while (size-- > 0) {
string s = q.front();
q.pop();
int p = s.find('0');
int y = p / kCols;
int x = p % kCols;
for (int i = 0; i < 4; ++i) {
int tx = x + dirs[i][0];
int ty = y + dirs[i][1];
if (tx < 0 || ty < 0 || tx >= kCols || ty >= kRows) continue;
int pp = ty * kCols + tx;
string t(s);
swap(t[p], t[pp]);
if (visited.count(t)) continue;
if (t == goal) return steps;
visited.insert(t);
q.push(t);
}
}
}
return -1;
}
};
Explain:
nope.
Complexity:
- Time complexity : O(n).
- Space complexity : O(n).