在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字(上下左右)进行交换.

在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字(上下左右)进行交换.
最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。
给出一个谜板的初始状态 board ,返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。
示例 1:
输入:board = [[1,2,3],[4,0,5]]
输出:1
解释:交换 0 和 5 ,1 步完成
示例 2:
输入:board = [[1,2,3],[5,4,0]]
输出:-1
解释:没有办法完成谜板
示例 3:
输入: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]]
提示:
board.length == 2
board[i].length == 3
0 <= board[i][j] <= 5
board[i][j] 中每个值都 不同
Please complete the following python code precisely.

class Solution:
    def slidingPuzzle(self, board: List[List[int]]) -> int:

解答
为了解决这个问题,我们可以使用广度优先搜索(BFS)来遍历所有可能的移动,直到找到目标状态或确定无解。

首先,我们需要定义一个函数来检查给定的板状态是否为目标状态。然后,我们需要一个函数来生成所有可能的下一个状态,即移动0到其相邻位置。

最后,我们使用BFS来遍历所有状态,直到找到目标状态或遍历完所有可能的状态。

以下是完整的Python代码实现:

from collections import deque  
  
class Solution:  
    def slidingPuzzle(self, board: List[List[int]]) -> int:  
        # 定义目标状态  
        target = [[1, 2, 3], [4, 5, 0]]  
          
        # 将二维列表转换为一维列表,方便后续操作  
        flat_board = [item for row in board for item in row]  
          
        # 定义四个方向的偏移量  
        directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]  
          
        # 检查当前状态是否为目标状态  
        def is_target(board):  
            return board == target  
          
        # 获取0的位置  
        def get_zero_pos(board):  
            for i, num in enumerate(flat_board):  
                if num == 0:  
                    return i // 3, i % 3  
          
        # 生成所有可能的下一个状态  
        def get_next_states(board):  
            x, y = get_zero_pos(board)  
            next_states = []  
            for dx, dy in directions:  
                nx, ny = x + dx, y + dy  
                if 0 <= nx < 2 and 0 <= ny < 3:  
                    new_board = flat_board[:]  
                    new_board[x * 3 + y], new_board[nx * 3 + ny] = new_board[nx * 3 + ny], new_board[x * 3 + y]  
                    next_states.append(new_board)  
            return next_states  
          
        # 初始化BFS队列和访问集合  
        queue = deque([(flat_board, 0)])  # (state, steps)  
        visited = set([tuple(flat_board)])  
          
        while queue:  
            current_state, steps = queue.popleft()  
              
            if is_target(current_state):  
                return steps  
              
            for next_state in get_next_states(current_state):  
                if tuple(next_state) not in visited:  
                    visited.add(tuple(next_state))  
                    queue.append((next_state, steps + 1))  
          
        return -1  # 如果遍历完所有状态仍未找到目标状态,则返回-1

注意:在代码中,我将二维列表board转换为一维列表flat_board,以便更方便地进行索引和交换操作。同时,为了避免在访问集合中存储列表(因为列表是不可哈希的),我将列表转换为元组后再存入访问集合中。

此外,我还使用了一个队列queue来存储待处理的状态和对应的步数,以及一个访问集合visited来记录已经访问过的状态,以避免重复访问。

最后,当队列为空时,说明已经遍历完所有可能的状态,但仍未找到目标状态,此时返回-1表示无解。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值