Sliding Puzzle solution and explanation
9 more videos on this problem
Sliding Puzzle - Leetcode 773 - PythonNeetCodeIO · 13:24 · 13K views
Sliding Puzzle | Detailed for Beginners | Leetcode 773 | codestorywithMIKcodestorywithMIK · 34:24 · 10K views
LeetCode 773 Sliding Puzzle BFS Walkthrough and ExplanationGregory Li · 8:18 · 4K views
Sliding Puzzle | Leetcode 773Techdose · 21:31 · 3K views
773. Sliding Puzzle | BFS | Graph Traversal | Matrix | ArrayAryan Mittal · 15:06 · 2K views
773. Sliding Puzzle (Leetcode Hard)Programming Live with Larry · 51:57 · 1K views
Leetcode 773 Sliding Puzzle - Hard Coding Interview Question - Solved And Explained Step By StepAlgorithmicIQ · 27:21 · 1K views
Solving LeetCode 773 Sliding Puzzle | Recursive Thinking | Uber | Airbnb Interview QuestionCode Harmony · 27:48 · 601 views
LeetCode 773 - Sliding Puzzle - JavaAlpha-Code · 13:49 · 272 views
Leetcode 773. Sliding Puzzlefengshuo li · 5:19 · 254 views
The 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 == 2board[i].length == 30 <= board[i][j] <= 5- Each value
board[i][j]is unique.
Approach overview
Problem Overview: You are given a 2x3 board containing numbers 1–5 and an empty tile represented by 0. Each move swaps the empty tile with one of its adjacent tiles. The task is to determine the minimum number of moves required to reach the target configuration [[1,2,3],[4,5,0]]. If the configuration cannot reach the goal state, return -1.
Approach 1: Breadth-First Search (BFS) (Time: O((m*n)!), Space: O((m*n)!))
This puzzle naturally forms a graph where each board configuration is a node and each valid tile swap is an edge. Breadth-First Search works well because every move has equal cost, and BFS guarantees the shortest path to the goal. Convert the board into a string such as "123450" so configurations can be stored in a hash set for fast visited checks. For every state, locate the index of 0, generate neighbors by swapping it with valid adjacent indices, and push unseen states into the queue. Since the puzzle has at most 6! = 720 states, BFS quickly explores all reachable configurations. This approach is straightforward and reliable for interview settings.
The board itself can be treated like a flattened array, and adjacency rules define which indices the blank tile can swap with. Using a visited set prevents revisiting states and avoids exponential blow‑up.
Approach 2: A* Search Algorithm (Time: O(b^d) worst case, typically faster; Space: O(b^d))
A* search improves exploration efficiency by prioritizing states closer to the goal. Each state is assigned a score f(n) = g(n) + h(n), where g(n) is the number of moves taken so far and h(n) is a heuristic estimating remaining distance. A common heuristic for sliding puzzles is the Manhattan distance between each tile’s current and target positions in the matrix. The algorithm stores states in a priority queue ordered by the smallest estimated total cost.
When expanding nodes, generate neighboring configurations the same way as BFS by swapping the blank tile. The heuristic guides the search toward promising states instead of exploring blindly. For larger sliding puzzles (like 8‑puzzle or 15‑puzzle), A* dramatically reduces the number of explored states compared to BFS. Even for the 2x3 variant, it demonstrates how heuristic search works in pathfinding problems.
Recommended for interviews: BFS is usually the expected solution because it clearly models the puzzle as an unweighted graph and guarantees the minimum number of moves. Implementing BFS with a queue and visited set demonstrates solid understanding of state‑space traversal. A* is a strong follow‑up optimization that shows deeper knowledge of heuristic search and algorithm design.
Approach 1: Breadth-First Search (BFS) Approach
from collections import deque
def sliding_puzzle(board):
start = ''.join(str(num) for row in board for num in row)
target = '123450'
neighbors = {
0: [1, 3],
1: [0, 2, 4],
2: [1, 5],
3: [0, 4],
4: [3, 1, 5],
5: [2, 4]
}
queue = deque([(start, start.index('0'), 0)]) # (board_str, zero_index, depth)
visited = {start}
while queue:
board_str, zero_index, depth = queue.popleft()
if board_str == target:
return depth
for adj in neighbors[zero_index]:
new_board = list(board_str)
new_board[zero_index], new_board[adj] = new_board[adj], new_board[zero_index]
new_board_str = ''.join(new_board)
if new_board_str not in visited:
visited.add(new_board_str)
queue.append((new_board_str, adj, depth + 1))
return -1using System;
using System.Collections.Generic;
public class Solution {
public int SlidingPuzzle(int[][] board) {
string start = string.Join("", board[0]) + string.Join("", board[1]);
string target = "123450";
int[][] neighbors = {
new int[] {1, 3},
new int[] {0, 2, 4},
new int[] {1, 5},
new int[] {0, 4},
new int[] {3, 1, 5},
new int[] {2, 4}
};
Queue<(string, int)> queue = new Queue<(string, int)>();
queue.Enqueue((start, 0));
HashSet<string> visited = new HashSet<string> { start };
while (queue.Count > 0) {
(string status, int steps) = queue.Dequeue();
if (status == target) return steps;
int zeroIndex = status.IndexOf('0');
foreach (int adj in neighbors[zeroIndex]) {
char[] newStatus = status.ToCharArray();
(newStatus[zeroIndex], newStatus[adj]) = (newStatus[adj], newStatus[zeroIndex]);
string newBoard = new string(newStatus);
if (!visited.Contains(newBoard)) {
visited.Add(newBoard);
queue.Enqueue((newBoard, steps + 1));
}
}
}
return -1;
}
}This Python code uses a BFS approach to solve the sliding puzzle. We convert the board into a string and use a map to determine swap positions for '0'. Initially, each configuration is enqueued with its depth. The goal is to find the shortest path to the solved state.
Time Complexity: O(1) - There are a constant number of states (720) due to permutation limits.
Space Complexity: O(1) - As with time, space usage peaks at 720 given state permutations.
Approach 2: A* Search Algorithm
import java.util.*;
public class Solution {
public int slidingPuzzle(int[][] board) {
PriorityQueue<Node> pq = new PriorityQueue<>();
String start = Arrays.deepToString(board).replaceAll("[^\d]", "");
String target = "123450";
int[][] neighbor = {{1, 3}, {0, 2, 4}, {1, 5}, {0, 4}, {3, 1, 5}, {2, 4}};
pq.add(new Node(start, 0, heuristic(start, target)));
Set<String> visited = new HashSet<>();
while (!pq.isEmpty()) {
Node current = pq.poll();
if (current.value.equals(target)) {
return current.depth;
}
int zeroIndex = current.value.indexOf('0');
visited.add(current.value);
for (int adj : neighbor[zeroIndex]) {
char[] newBoardArray = current.value.toCharArray();
char temp = newBoardArray[adj];
newBoardArray[adj] = newBoardArray[zeroIndex];
newBoardArray[zeroIndex] = temp;
String newBoard = new String(newBoardArray);
if (!visited.contains(newBoard)) {
pq.offer(new Node(newBoard, current.depth + 1, heuristic(newBoard, target)));
}
}
}
return -1;
}
private int heuristic(String state, String goal) {
int dist = 0;
for (int i = 0; i < state.length(); i++) {
if (state.charAt(i) != '0') {
int targetPosition = goal.indexOf(state.charAt(i));
dist += Math.abs(targetPosition / 3 - i / 3) + Math.abs(targetPosition % 3 - i % 3);
}
}
return dist;
}
class Node implements Comparable<Node> {
String value;
int depth;
int cost;
Node(String v, int d, int c) {
value = v;
depth = d;
cost = d + c;
}
@Override
public int compareTo(Node other) {
return Integer.compare(this.cost, other.cost);
}
}
}#include <iostream>
#include <unordered_set>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
struct Node {
string board;
int depth;
int cost;
bool operator<(const Node& other) const {
return cost > other.cost;
}
};
int slidingPuzzle(vector<vector<int>>& board) {
string start;
for (auto &row : board)
for (auto &num : row)
start += to_string(num);
string target = "123450";
vector<vector<int>> neighbor = {{1, 3}, {0, 2, 4}, {1, 5}, {0, 4}, {3, 1, 5}, {2, 4}};
priority_queue<Node> pq;
unordered_set<string> visited;
pq.push({start, 0, heuristic(start, target)});
while (!pq.empty()) {
Node current = pq.top(); pq.pop();
if (current.board == target) {
return current.depth;
}
visited.insert(current.board);
int zeroIndex = current.board.find('0');
for (int adj : neighbor[zeroIndex]) {
string newBoard = current.board;
swap(newBoard[zeroIndex], newBoard[adj]);
if (visited.find(newBoard) == visited.end()) {
pq.push({newBoard, current.depth + 1, current.depth + 1 + heuristic(newBoard, target)});
}
}
}
return -1;
}
int heuristic(const string& state, const string& goal) {
int dist = 0;
for (int i = 0; i < state.length(); i++) {
if (state[i] != '0') {
int targetPosition = goal.find(state[i]);
dist += abs(targetPosition / 3 - i / 3) + abs(targetPosition % 3 - i % 3);
}
}
return dist;
}This Java code implements the A* search algorithm to tackle the sliding puzzle. Nodes are compared based on the cost estimation which combines depth and heuristic calculations. Using Manhattan distance as a heuristic ensures the solution is efficiently discovered through optimal path estimation.
Time Complexity: O((6! = 720) log(720))
Space Complexity: O(720), based on the number of states handled.
Complexity comparison
| Approach | Complexity |
|---|---|
| Breadth-First Search (BFS) Approach | Time Complexity: O(1) - There are a constant number of states (720) due to permutation limits. |
| A* Search Algorithm | Time Complexity: O((6! = 720) log(720)) |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Breadth-First Search (BFS) | O((m*n)!) ≈ O(720) for 2x3 board | O((m*n)!) | Best general solution for shortest path in an unweighted puzzle state graph |
| A* Search Algorithm | O(b^d) worst case, typically faster with heuristic | O(b^d) | When heuristic guidance (like Manhattan distance) can reduce explored states |
Frequently asked questions
Is Sliding Puzzle easy or hard?
Sliding Puzzle is classified as a Hard problem because it requires modeling the board as a graph and implementing efficient state exploration. The difficulty comes from generating valid neighbors, avoiding repeated states, and recognizing BFS or A* as the correct approach.
Sliding Puzzle Python/Java solution
Python solutions commonly implement BFS using collections.deque and a set for visited states. Java implementations use Queue with HashSet for visited tracking, while A* variants use PriorityQueue. The algorithm logic is identical: generate neighbor states by swapping the zero tile and search until the target configuration appears.
How to solve Sliding Puzzle in O(n)?
Sliding Puzzle cannot generally be solved in strict O(n) time because it requires exploring permutations of board states. The optimal approach is BFS or A* search that explores the state graph efficiently. For the 2x3 puzzle, BFS effectively runs in constant time since there are only 720 possible configurations.
What is the best approach for Sliding Puzzle?
Breadth-First Search (BFS) is the most common approach because the puzzle can be modeled as an unweighted graph of board states. BFS explores configurations level by level, guaranteeing the minimum number of moves to reach the target state. For a 2x3 board the total number of states is only 720, making BFS efficient and easy to implement.
Is Sliding Puzzle asked at Google/Amazon/Meta?
Sliding puzzle style problems appear in interviews at companies like Google, Amazon, and Meta when testing graph traversal and state-space search. Interviewers use it to evaluate BFS, hashing for visited states, and understanding of shortest path problems in implicit graphs.
What data structure is used in Sliding Puzzle?
The typical solution uses a queue for BFS traversal and a hash set to track visited board configurations. The board is usually converted into a string representation like "123450" so it can be stored and compared efficiently. A* solutions additionally use a priority queue (min-heap).
What is the time complexity of Sliding Puzzle?
The BFS solution has time complexity O((m*n)!) because every board permutation may be explored in the worst case. For the 2x3 puzzle used in LeetCode 773, this is at most 6! = 720 states, so the search is effectively constant time. Space complexity is also O((m*n)!) due to the queue and visited set.
