滑动谜题 -- 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)
相关推荐
夏日听雨眠1 小时前
linux(线程,线程同步 方法 互斥锁 信号量 条件变量 )
linux·运维·算法
神经网络机器学习智能算法画图绘图1 小时前
基于改进的支持向量机多分类预测研究
算法·支持向量机·分类
阿Y加油吧1 小时前
两道经典算法题复盘:最长有效括号 & 不同路径
算法
晚风叙码1 小时前
一文吃透二叉树:前中后序遍历+节点数+树高+叶子节点(含完整源码)
数据结构·算法
迦南的迦 亚索的索1 小时前
机器学习_05_k-means算法
算法·机器学习·kmeans
happymaker06261 小时前
LeetCodeHot100——1.两数之和(详细解答)
java·数据结构·学习·算法
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第60题】【JVM篇】第20题:垃圾收集算法和垃圾收集器有什么区别?
java·jvm·算法·面试
@ray3211 小时前
LeetCode Hot 100 — C++ 题解
c++·算法·leetcode
大模型最新论文速读1 小时前
利用异步编程的 future 思想,让 LLM Agent 快 1.44 倍
人工智能·深度学习·算法·机器学习·自然语言处理
Bingorl1 小时前
机器学习之线性回归算法
算法·机器学习·线性回归