滑动谜题 -- 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)
相关推荐
大二转专业37 分钟前
408算法题leetcode--第24天
考研·算法·leetcode
凭栏落花侧43 分钟前
决策树:简单易懂的预测模型
人工智能·算法·决策树·机器学习·信息可视化·数据挖掘·数据分析
hong_zc2 小时前
算法【Java】—— 二叉树的深搜
java·算法
吱吱鼠叔3 小时前
MATLAB计算与建模常见函数:5.曲线拟合
算法·机器学习·matlab
嵌入式AI的盲4 小时前
数组指针和指针数组
数据结构·算法
Indigo_code6 小时前
【数据结构】【顺序表算法】 删除特定值
数据结构·算法
阿史大杯茶7 小时前
Codeforces Round 976 (Div. 2 ABCDE题)视频讲解
数据结构·c++·算法
LluckyYH7 小时前
代码随想录Day 58|拓扑排序、dijkstra算法精讲,题目:软件构建、参加科学大会
算法·深度优先·动态规划·软件构建·图论·dfs
转调7 小时前
每日一练:地下城游戏
开发语言·c++·算法·leetcode
不穿格子衬衫8 小时前
常用排序算法(下)
c语言·开发语言·数据结构·算法·排序算法·八大排序