滑动谜题 -- 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)
相关推荐
田梓燊5 小时前
力扣:23.合并 K 个升序链表
算法·leetcode·链表
re林檎5 小时前
算法札记——4.27
算法
数据牧羊人的成长笔记6 小时前
逻辑回归与Softmax回归
算法·回归·逻辑回归
郑州光合科技余经理6 小时前
同城O2O海外版二次开发实战:从支付网关到配送算法
开发语言·前端·后端·算法·架构·uni-app·php
d111111111d9 小时前
STM32-UART封装问题解析
笔记·stm32·单片机·嵌入式硬件·学习·算法
Jiangxl~11 小时前
IP数据云如何为不同行业提供精准IP查询与风险防控解决方案?
网络·网络协议·tcp/ip·算法·ai·ip·安全架构
李伟_Li慢慢11 小时前
wolfram详解山峦算法
前端·算法
counting money11 小时前
prim算法最小生成树(java)
算法
澈20712 小时前
C++面向对象:类与对象核心解析
c++·算法
用户6906738819212 小时前
基于无人机的单目测距系统,平均误差仅2.12%
算法