↓Skip to main content
  1. LeetCode/

LeetCode 773: Sliding Puzzle

·2 mins· ·
LeetCode Hard Breadth-First-Search Dynamic-Programming Memoization Matrix
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: hard First Attempt: 2026-09-07

  • Submissions: Accepted (first try)

Approach
#

A 2 × 3 board has only 6! = 720 arrangements, so the whole board can be a state for BFS, where the first time the target is reached gives the fewest moves (see state-space BFS in BFS).

  • State: the board flattened into a 6-character string, e.g. "412503".
  • Move: find 0 and swap it with an adjacent cell. After flattening, each position’s neighbors are fixed, so write them as a table:
0 1 2
3 4 5

0: [1, 3], 1: [0, 2, 4], 2: [1, 5], 3: [0, 4], 4: [1, 3, 5], 5: [2, 4].

If BFS ends without reaching "123450", return -1.

My Solution
#

from collections import deque

class Solution:
    def slidingPuzzle(self, board: List[List[int]]) -> int:
        start = "".join(str(x) for row in board for x in row)
        target = "123450"
        neighbors = {0: [1, 3], 1: [0, 2, 4], 2: [1, 5], 3: [0, 4], 4: [1, 3, 5], 5: [2, 4]}

        queue = deque([(start, 0)])
        seen = {start}
        while queue:
            state, moves = queue.popleft()
            if state == target:
                return moves
            z = state.index("0")
            for nb in neighbors[z]:
                s = list(state)
                s[z], s[nb] = s[nb], s[z]
                nxt = "".join(s)
                if nxt not in seen:
                    seen.add(nxt)
                    queue.append((nxt, moves + 1))
        return -1

Complexity
#

At most 720 states with at most 3 neighbors each: constant time.

Mistakes to Avoid
#

  • Using a list as the state: lists cannot go in a set; use a string or tuple.
  • Mind the row break when flattening: positions 2 and 3 are not adjacent.

Interview Explanation
#

There are only 720 boards, so I flatten each board into a string as a BFS state, swap 0 with an adjacent cell each move, dedupe with seen, and the first arrival at the target is the fewest moves; otherwise return -1. A neighbor table avoids treating the two cells across the row break as adjacent.

Related

LeetCode 2328: Number of Increasing Paths in a Grid
·2 mins
LeetCode Hard Dynamic-Programming Grid-Dp Memoization Topological-Sort Matrix
LeetCode 2328 note: strictly increasing means no cycles; dp[cell] = 1 + Σ dp[larger neighbors], processed from largest to smallest value (or by memoized DFS), summed over all cells
LeetCode 488: Zuma Game
·3 mins
LeetCode Hard Dynamic-Programming Memoization Breadth-First-Search String Stack
LeetCode 488 note: with at most 16 balls on the board and 5 in hand, memoize DFS on the whole (board, hand) state, inserting only before a same-colored ball or between two equal balls
LeetCode 4041: Minimum Operations to Form Subset Sum II
·2 mins
LeetCode Hard Dynamic-Programming Knapsack Breadth-First-Search Array
LeetCode 4041 note: with operations in any order, BFS finds every value a number can become (up to sum) with the fewest steps, then the same grouped 0/1 knapsack as 4040
LeetCode 3989: Maximum Consistent Columns in a Grid
·2 mins
LeetCode Hard Dynamic-Programming Matrix Array
LeetCode 3989 note: the kept columns form a subsequence constrained only between neighbors; an LIS-style DP with dp[j] = the longest valid sequence ending at column j
LeetCode 3651: Minimum Cost Path with Teleportations
·2 mins
LeetCode Hard Dynamic-Programming Grid-Dp Matrix Array
LeetCode 3651 note: compute layer by layer over teleports; arriving at a cell by teleport costs the previous layer’s minimum over cells with value >= it, found with a running minimum after sorting, followed by the usual right / down grid DP
LeetCode 2163: Minimum Difference in Sums After Removal of Elements
·2 mins
LeetCode Hard Dynamic-Programming Heap Array
LeetCode 2163 note: try every boundary k between the two parts; the left takes the n smallest of nums[:k] (a max-heap) and the right the n largest of nums[k:] (a min-heap), one prefix and one suffix pass