打开锁 - BFS 应用程序

Open the Lock - BFS Application

刚刚学习了BFS算法,正在尝试应用BFS算法来解决这里的leetcode问题Open the Lock

我的算法适用于某些用例,而对其他用例输出错误答案。任何人都可以帮助我了解我所缺少的吗?

提前致谢

    class Solution {
    Queue<String> queue = new LinkedList<String>();
    HashSet<String> deads = new HashSet<String>();
    public int openLock(String[] deadends, String target) {
        for(int i  = 0; i < deadends.length; i++){
            deads.add(deadends[i]);
        }
        if(deads.contains("0000"))return -1;
        int level  = bfs("0000", target);
        return level;
    
    }
public int bfs(String start, String target){
        int level  = 0;
        queue.add(start); // add the start to the queue
        deads.add(start);
        while(!queue.isEmpty()){
            int groupSize = queue.size();
            while(groupSize >0){
                String current = queue.poll();
                if(current.equals(target)) return level;
                for(int i  = 0; i < current.length(); i++){
                    char c = current.charAt(i);
                    char temp  = c;
                    if( c == '9'){
                        c = '0';
                        temp  = c;
                    }else{
                        c++;
                    }
                    String upString = current.substring(0, i) + c + current.substring(i + 1);
                    if(!deads.contains(upString)){
                        queue.add(upString);
                        deads.add(upString);
                    }
                    c = temp;
                    if( c == '0'){
                        c = '9';
                    }
                    else{
                        c--;
                    }
                    String downString = current.substring(0, i) + c + current.substring(i + 1);
                    if(!deads.contains(downString)){
                        queue.add(downString);
                        deads.add(downString);
                    }
                }
                groupSize = groupSize - 1;
            }
            level = level + 1;
        }
        return -1;
    }
}

不太确定你的算法可能有什么问题,我觉得还不错,可能是一些小问题需要修复。

几乎相同的方法,除了我们将使用三个集合来解决 Java 中的问题:

public final class Solution {
    public static final int openLock(
        final String[] deadends,
        final String target
    ) {
        Set<String> startSet = new HashSet<>();
        Set<String> endSet = new HashSet<>();
        Set<String> deadSet = new HashSet<>(Arrays.asList(deadends));
        startSet.add("0000");
        endSet.add(target);
        int minTurns = 0;
        Set<String> tempSet;

        while (!startSet.isEmpty() && !endSet.isEmpty()) {
            if (startSet.size() > endSet.size()) {
                tempSet = startSet;
                startSet = endSet;
                endSet = tempSet;
            }

            tempSet = new HashSet<>();

            for (String start : startSet) {
                if (endSet.contains(start)) {
                    return minTurns;
                }

                if (deadSet.contains(start)) {
                    continue;
                }

                deadSet.add(start);
                StringBuilder startSB = new StringBuilder(start);

                for (int i = 0; i < 4; i++) {
                    final char character = startSB.charAt(i);
                    String s1 = startSB.substring(0, i) + (character == '9' ? 0 : character - '0' + 1) + startSB.substring(i + 1);
                    String s2 = startSB.substring(0, i) + (character == '0' ? 9 : character - '0' - 1) + startSB.substring(i + 1);

                    if (!deadSet.contains(s1)) {
                        tempSet.add(s1);
                    }

                    if (!deadSet.contains(s2)) {
                        tempSet.add(s2);
                    }
                }
            }

            minTurns++;
            startSet = tempSet;
        }

        return -1;
    }
}

好的!下面是 LeetCode 的 BFS 解法,你可以根据这个解法:

class Solution {
    public int openLock(String[] deadends, String target) {
        Set<String> dead = new HashSet();
        for (String d: deadends) dead.add(d);

        Queue<String> queue = new LinkedList();
        queue.offer("0000");
        queue.offer(null);

        Set<String> seen = new HashSet();
        seen.add("0000");

        int depth = 0;
        while (!queue.isEmpty()) {
            String node = queue.poll();
            if (node == null) {
                depth++;
                if (queue.peek() != null)
                    queue.offer(null);
            } else if (node.equals(target)) {
                return depth;
            } else if (!dead.contains(node)) {
                for (int i = 0; i < 4; ++i) {
                    for (int d = -1; d <= 1; d += 2) {
                        int y = ((node.charAt(i) - '0') + d + 10) % 10;
                        String nei = node.substring(0, i) + ("" + y) + node.substring(i+1);
                        if (!seen.contains(nei)) {
                            seen.add(nei);
                            queue.offer(nei);
                        }
                    }
                }
            }
        }
        return -1;
    }
}

看来他们已经为这个问题添加了新的测试用例。


参考资料

  • 有关更多详细信息,请参阅 Discussion Board where you can find plenty of well-explained accepted solutions with a variety of languages including low-complexity algorithms and asymptotic runtime/memory analysis1, 2
 class Solution {
    Queue<String> queue = new LinkedList<String>();
    HashSet<String> deads = new HashSet<String>();
    public int openLock(String[] deadends, String target) {
        for(int i  = 0; i < deadends.length; i++){
            deads.add(deadends[i]);
        }
        if(deads.contains("0000"))return -1;
        int level  = bfs("0000", target);
        return level;
    
    }
public int bfs(String start, String target){
        int level  = 0;
        queue.add(start); // add the start to the queue
        deads.add(start);
        while(!queue.isEmpty()){
            int groupSize = queue.size();
            while(groupSize >0){
                String current = queue.poll();
                if(current.equals(target)) return level;
                for(int i  = 0; i < current.length(); i++){
                    char c = current.charAt(i);
                    char temp  = c;
                    if( c == '9'){
                        c = '0';
                        temp  = c; // THIS LINE IS THE ISSUE. REMOVING IT HELPED!!!!
                    }else{
                        c++;
                    }
                    String upString = current.substring(0, i) + c + current.substring(i + 1);
                    if(!deads.contains(upString)){
                        queue.add(upString);
                        deads.add(upString);
                    }
                    c = temp;
                    if( c == '0'){
                        c = '9';
                    }
                    else{
                        c--;
                    }
                    String downString = current.substring(0, i) + c + current.substring(i + 1);
                    if(!deads.contains(downString)){
                        queue.add(downString);
                        deads.add(downString);
                    }
                }
                groupSize = groupSize - 1;
            }
            level = level + 1;
        }
        return -1;
    }
}