Welcome to Subscribe On Youtube
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
A* search.
-
class Solution { private int m = 2; private int n = 3; public int slidingPuzzle(int[][] board) { String start = ""; String end = "123450"; String seq = ""; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { start += board[i][j]; if (board[i][j] != 0) { seq += board[i][j]; } } } if (!check(seq)) { return -1; } PriorityQueue<Pair<Integer, String>> q = new PriorityQueue<>(Comparator.comparingInt(Pair::getKey)); Map<String, Integer> dist = new HashMap<>(); dist.put(start, 0); q.offer(new Pair<>(f(start), start)); int[] dirs = {-1, 0, 1, 0, -1}; while (!q.isEmpty()) { String state = q.poll().getValue(); int step = dist.get(state); if (end.equals(state)) { return step; } int p1 = state.indexOf("0"); int i = p1 / n, j = p1 % n; char[] s = state.toCharArray(); for (int k = 0; k < 4; ++k) { int x = i + dirs[k], y = j + dirs[k + 1]; if (x >= 0 && x < m && y >= 0 && y < n) { int p2 = x * n + y; swap(s, p1, p2); String next = String.valueOf(s); if (!dist.containsKey(next) || dist.get(next) > step + 1) { dist.put(next, step + 1); q.offer(new Pair<>(step + 1 + f(next), next)); } swap(s, p1, p2); } } } return -1; } private void swap(char[] arr, int i, int j) { char t = arr[i]; arr[i] = arr[j]; arr[j] = t; } private int f(String s) { int ans = 0; for (int i = 0; i < m * n; ++i) { if (s.charAt(i) != '0') { int num = s.charAt(i) - '1'; ans += Math.abs(i / n - num / n) + Math.abs(i % n - num % n); } } return ans; } private boolean check(String s) { int n = s.length(); int cnt = 0; for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { if (s.charAt(i) > s.charAt(j)) { ++cnt; } } } return cnt % 2 == 0; } }
-
class Solution { public: int m = 2; int n = 3; int slidingPuzzle(vector<vector<int>>& board) { string start, seq; string end = "123450"; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { start += char(board[i][j] + '0'); if (board[i][j] != 0) seq += char(board[i][j] + '0'); } } if (!check(seq)) return -1; typedef pair<int, string> PIS; priority_queue<PIS, vector<PIS>, greater<PIS>> q; unordered_map<string, int> dist; dist[start] = 0; q.push({f(start), start}); vector<int> dirs = {-1, 0, 1, 0, -1}; while (!q.empty()) { PIS t = q.top(); q.pop(); string state = t.second; int step = dist[state]; if (state == end) return step; int p1 = state.find('0'); int i = p1 / n, j = p1 % n; for (int k = 0; k < 4; ++k) { int x = i + dirs[k], y = j + dirs[k + 1]; if (x < 0 || x >= m || y < 0 || y >= n) continue; int p2 = x * n + y; swap(state[p1], state[p2]); if (!dist.count(state) || dist[state] > step + 1) { dist[state] = step + 1; q.push({step + 1 + f(state), state}); } swap(state[p1], state[p2]); } } return -1; } bool check(string s) { int n = s.size(); int cnt = 0; for (int i = 0; i < n; ++i) for (int j = i; j < n; ++j) if (s[i] > s[j]) ++cnt; return cnt % 2 == 0; } int f(string s) { int ans = 0; for (int i = 0; i < m * n; ++i) { if (s[i] == '0') continue; int num = s[i] - '1'; ans += abs(num / n - i / n) + abs(num % n - i % n); } return ans; } };
-
class Solution: def slidingPuzzle(self, board: List[List[int]]) -> int: m, n = 2, 3 seq = [] start, end = '', '123450' for i in range(m): for j in range(n): if board[i][j] != 0: seq.append(board[i][j]) start += str(board[i][j]) def check(seq): n = len(seq) cnt = sum(seq[i] > seq[j] for i in range(n) for j in range(i, n)) return cnt % 2 == 0 def f(s): ans = 0 for i in range(m * n): if s[i] != '0': num = ord(s[i]) - ord('1') ans += abs(i // n - num // n) + abs(i % n - num % n) return ans if not check(seq): return -1 q = [(f(start), start)] dist = {start: 0} while q: _, state = heappop(q) if state == end: return dist[state] p1 = state.index('0') i, j = p1 // n, p1 % n s = list(state) for a, b in [[0, -1], [0, 1], [1, 0], [-1, 0]]: x, y = i + a, j + b if 0 <= x < m and 0 <= y < n: p2 = x * n + y s[p1], s[p2] = s[p2], s[p1] next = ''.join(s) s[p1], s[p2] = s[p2], s[p1] if next not in dist or dist[next] > dist[state] + 1: dist[next] = dist[state] + 1 heappush(q, (dist[next] + f(next), next)) return -1