leetcode 752. 打开转盘锁 --广度优先搜索BFS以及双向BFS(Java实现)

题目

leetcode 752. 打开转盘锁

解法一:单向BFS

// 单向BFS
class Solution {
    public int openLock(String[] deadends, String target) {
        int step = 0;
        Set<String> deadSet = new HashSet<>();
        for (String deadString : deadends)
            deadSet.add(deadString);
        Set<String> vis = new HashSet<>();
        Queue<String> q = new LinkedList<>();
        q.offer("0000");
        vis.add("0000");
        while (!q.isEmpty()) {
            int sz = q.size();
            for (int i = 0; i < sz; i++) {
                String now = q.poll();
                // 判断是否到达终点
                if (now.equals(target))
                    return step;
                if (deadSet.contains(now))
                    continue;

                // 加入新状态
                for (int j = 0; j < 4; j++) {
                    String up = plus(now, j);
                    String down = minus(now, j);
                    if (!vis.contains(up)) {
                        q.offer(up);
                        vis.add(up);
                    }
                    if (!vis.contains(down)) {
                        q.offer(down);
                        vis.add(down);
                    }
                }
            }
            step++;
        }
        return -1;
    }

    private String plus(String str, int pos) {
        char[] chars = str.toCharArray();
        if (chars[pos] == '9') chars[pos] = '0';
        else chars[pos] += 1;
        return new String(chars);
    }

    private String minus(String str, int pos) {
        char[] chars = str.toCharArray();
        if (chars[pos] == '0') chars[pos] = '9';
        else chars[pos] -= 1;
        return new String(chars);
    }
}

解法二

// 双向BFS
class Solution {
    public int openLock(String[] deadends, String target) {
        Set<String> deads = new HashSet<>();
        for (String s : deadends) deads.add(s);
        Set<String> vis = new HashSet<>();
        Set<String> q1 = new HashSet<>();
        Set<String> q2 = new HashSet<>();
        int step = 0;
        q1.add("0000");
        q2.add(target);
        while (!q1.isEmpty() && !q2.isEmpty()) {
            Set<String> tmp = new HashSet<>();

            for (String now : q1) {
                // 判断是否到达终点
                if (q2.contains(now))
                    return step;
                if (deads.contains(now))
                    continue;

                vis.add(now);

                // 加入新状态
                for (int j = 0; j < 4; j++) {
                    String up = plus(now, j);
                    if (!vis.contains(up)) tmp.add(up);
                    String down = minus(now, j);
                    if (!vis.contains(down)) tmp.add(down);
                }
            }
            step++;
            q1 = q2;
            q2 = tmp;
        }
        return -1;
    }

    private String plus(String str, int pos) {
        char[] chars = str.toCharArray();
        if (chars[pos] == '9')
            chars[pos] = '0';
        else
            chars[pos] += 1;
        return new String(chars);
    }

    private String minus(String str, int pos) {
        char[] chars = str.toCharArray();
        if (chars[pos] == '0')
            chars[pos] = '9';
        else
            chars[pos] -= 1;
        return new String(chars);
    }
}

总结

  • 单向BFS从源点出发找目标,最坏情况下遍历整棵树;
  • 双向BFS从源点和目标同时出发,交替寻找交集,最坏情况遍历半棵树。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值