滑动谜题 -- BFS

滑动谜题

输入:board = [[4,1,2],[5,0,3]]

输出:5

解释:

最少完成谜板的最少移动次数是 5 ,

一种移动路径:

尚未移动: [[4,1,2],[5,0,3]]

移动 1 次: [[4,1,2],[0,5,3]]

移动 2 次: [[0,1,2],[4,5,3]]

移动 3 次: [[1,0,2],[4,5,3]]

移动 4 次: [[1,2,0],[4,5,3]]

移动 5 次: [[1,2,3],[4,5,0]]

python 复制代码
class SlidingPuzzle:
    """
    773. 滑动谜题
    https://leetcode.cn/problems/sliding-puzzle/
    """
    def solution(self, board: List[List[int]]) -> int:
        """

        :param board:
        :return:
        """
        m, n = len(board), len(board[0])
        target = '123450'
        start = ''
        for i in range(m):
            for j in range(n):
                start += str(board[i][j])

        # BFS算法 框架开始
        queue = []
        visited = set()
        step = 0
        nei_map = self.generateNeighborMapping(m, n)
        # 从起点开始BFS搜索
        queue.append(start)
        visited.add(start)

        while queue:
            sz = len(queue)
            for i in range(sz):
                cur = queue.pop(0)
                if cur == target:
                    return step

                idx = 0
                for _ in cur:
                    if cur[idx] == '0':
                        break
                    idx += 1

                for adj in nei_map[idx]:
                    new_board = self.swap(cur, adj, idx)
                    if new_board not in visited:
                        queue.append(new_board)
                        visited.add(new_board)
            step += 1

        return -1

    def generateNeighborMapping(self, m, n):
        """
        给定一个二维m*n数组,返回每个节点的邻居节点,用一维数组表示
        :param m:
        :param n:
        :return:
        """
        res = []
        for i in range(m*n):
            tmp = []
            # 如果i不是第一列,那么有左侧邻居
            if i % n != 0:
                tmp.append(i-1)

            # 如果i不是最后一列,那么有右侧邻居
            if i % n != n-1:
                tmp.append(i+1)

            # 如果i不是第一行,那么有上侧邻居
            if i - n >= 0:
                tmp.append(i-n)

            # 如果i不是最后一行,那么有下侧邻居
            if i + n < m*n:
                tmp.append(i+n)

            res.append(tmp)

        return res

    def swap(self, cur, idx, adj):
        cur_arr = list(cur)
        tmp = cur_arr[idx]
        cur_arr[idx] = cur_arr[adj]
        cur_arr[adj] = tmp
        return ''.join(cur_arr)
相关推荐
明朝百晓生10 分钟前
【强化学习】【1】【PyTorch】【强化学习简介优化框架】
算法
loser~曹15 分钟前
基于快速排序解决 leetcode hot215 查找数组中第k大的数字
数据结构·算法·leetcode
Dream it possible!21 分钟前
LeetCode 热题 100_打家劫舍(83_198_中等_C++)(动态规划)
c++·算法·leetcode·动态规划
zhouziyi070126 分钟前
【蓝桥杯14天冲刺课题单】Day 8
c++·算法·蓝桥杯
SylviaW0830 分钟前
python-leetcode 62.搜索插入位置
数据结构·算法·leetcode
舔甜歌姬的EGUMI LEGACY2 小时前
【算法day28】解数独——编写一个程序,通过填充空格来解决数独问题
算法
welkin2 小时前
KMP 个人理解
前端·算法
半桔2 小时前
红黑树剖析
c语言·开发语言·数据结构·c++·后端·算法
eason_fan2 小时前
前端面试手撕代码(字节)
前端·算法·面试
今天_也很困2 小时前
牛客2025年愚人节比赛
c++·算法