滑动谜题 -- 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)
相关推荐
maycho1231 小时前
starccm 汽车热管理仿真 本文向您展示了设置整车热管理(VTM)模拟的最佳实践
宽度优先
xlq223221 小时前
22.多态(下)
开发语言·c++·算法
CoderYanger1 小时前
C.滑动窗口-越短越合法/求最长/最大——2958. 最多 K 个重复元素的最长子数组
java·数据结构·算法·leetcode·哈希算法·1024程序员节
却话巴山夜雨时i2 小时前
394. 字符串解码【中等】
java·数据结构·算法·leetcode
haing20192 小时前
使用黄金分割法计算Bezier曲线曲率极值的方法介绍
算法·黄金分割
leoufung2 小时前
LeetCode 230:二叉搜索树中第 K 小的元素 —— 从 Inorder 遍历到 Order Statistic Tree
算法·leetcode·职场和发展
jyyyx的算法博客2 小时前
多模字符串匹配算法 -- 面试题 17.17. 多次搜索
算法
da_vinci_x2 小时前
Sampler AI + 滤波算法:解决 AIGC 贴图“噪点过剩”,构建风格化 PBR 工业管线
人工智能·算法·aigc·材质·贴图·技术美术·游戏美术
惊鸿.Jh2 小时前
503. 下一个更大元素 II
数据结构·算法·leetcode
chao1898442 小时前
MATLAB 实现声纹识别特征提取
人工智能·算法·matlab