752 打开转盘锁(宽搜)
发布日期:2021-05-07 21:50:06 浏览次数:19 分类:精选文章

本文共 3036 字,大约阅读时间需要 10 分钟。

为了解决这个问题,我们需要找到从初始状态"0000"到目标状态的最短旋转次数,同时避开死亡数字列表中的状态。我们可以使用广度优先搜索(BFS)来解决这个问题,因为BFS能够找到最短路径。

方法思路

  • 问题分析:我们需要从初始状态"0000"出发,每次只能旋转一个拨轮到目标状态。每个拨轮可以旋转10次,数字可以循环(如9旋转一次变成0,0旋转一次变成9)。如果在旋转过程中到达任何一个死亡状态,锁就会被永久锁定,无法继续旋转。

  • 算法选择:使用广度优先搜索(BFS)来找到从初始状态到目标状态的最短路径。BFS适合这种问题,因为它能逐层扩展,找到最短路径。

  • 状态表示:每个状态是一个四位字符串,表示四个拨轮的当前数字。每次旋转一个拨轮,生成新的状态。

  • 避免重复访问:使用集合来记录已经访问过的状态,避免重复处理。

  • 死亡状态检查:在生成每个新状态时,检查它是否在死亡状态列表中。如果是,跳过这个状态。

  • 解决代码

    import java.util.*;
    public class Solution {
    Set
    visited = new HashSet<>();
    Queue
    queue = new LinkedList<>();
    public int openLock(String[] deadends, String target) {
    // 预处理:如果初始状态在死锁列表中,直接返回-1
    for (String s : deadends) {
    if ("0000".equals(s)) {
    return -1;
    }
    }
    // 预处理死锁列表为集合,提高查询效率
    Set
    deadSet = new HashSet<>();
    for (String s : deadends) {
    deadSet.add(s);
    }
    // 初始化队列和已访问集合
    visited.add("0000");
    queue.add(new Node("0000", 0, "0000"));
    while (!queue.isEmpty()) {
    Node current = queue.poll();
    if (current.cur.equals(target)) {
    return current.step;
    }
    // 生成所有可能的下一步状态
    String[] nextStates = generateNextStates(current.cur);
    for (String state : nextStates) {
    if (!visited.contains(state)) {
    // 检查是否是死锁状态
    if (!deadSet.contains(state)) {
    visited.add(state);
    queue.add(new Node(state, current.step + 1, current.road + "-->" + state));
    }
    }
    }
    }
    return -1;
    }
    // 生成所有可能的下一步状态
    private String[] generateNextStates(String cur) {
    List
    nextStates = new ArrayList<>();
    for (int i = 0; i < 4; i++) {
    char c = cur.charAt(i);
    int num = c - '0';
    // 加1的情况
    int nextAdd = num + 1;
    if (nextAdd > 9) {
    nextAdd = 0;
    }
    String addState = cur.substring(0, i) + nextAdd + cur.substring(i + 1);
    nextStates.add(addState);
    // 减1的情况
    int nextSub = num - 1;
    if (nextSub < 0) {
    nextSub = 9;
    }
    String subState = cur.substring(0, i) + nextSub + cur.substring(i + 1);
    nextStates.add(subState);
    }
    return nextStates.toArray(new String[0]);
    }
    // 节点内部类
    static class Node {
    String cur;
    int step;
    String road;
    Node(String cur, int step, String road) {
    this.cur = cur;
    this.step = step;
    this.road = road;
    }
    }
    }

    代码解释

  • 预处理:检查初始状态是否在死亡状态列表中,若是,直接返回-1。将死亡状态列表转换为集合,提高查询效率。

  • BFS初始化:将初始状态"0000"加入队列,并标记为已访问。

  • 处理队列:每次从队列中取出当前状态,生成所有可能的下一步状态。

  • 生成下一步状态:对于每个位,生成加1和减1两种情况,生成新的状态字符串。

  • 状态检查:检查新状态是否在死亡状态列表中,若不在且未被访问过,将其加入队列。

  • 目标状态检查:如果当前状态是目标状态,返回当前步数。

  • 通过这种方法,我们可以找到从初始状态到目标状态的最短旋转次数,或者返回-1表示无法解锁。

    上一篇:127 单词接龙(宽搜)
    下一篇:20 有效的括号(栈的使用)

    发表评论

    最新留言

    第一次来,支持一个
    [***.219.124.196]2025年03月28日 01时30分06秒