打开锁 – 广度优先搜索应用

huangapple go评论105阅读模式
英文:

Open the Lock - BFS Application

问题

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;
    }
}
英文:

I have just learned the BFS algorithm and I am trying to apply the BFS algorithm to solve the leetcode problem here Open the Lock

My algorithm works for some usecases and outputs a wrong answer for the others. Can anyone help me understand what I am missing?

Thanks in advance

    class Solution {
Queue&lt;String&gt; queue = new LinkedList&lt;String&gt;();
HashSet&lt;String&gt; deads = new HashSet&lt;String&gt;();
public int openLock(String[] deadends, String target) {
for(int i  = 0; i &lt; deadends.length; i++){
deads.add(deadends[i]);
}
if(deads.contains(&quot;0000&quot;))return -1;
int level  = bfs(&quot;0000&quot;, 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 &gt;0){
String current = queue.poll();
if(current.equals(target)) return level;
for(int i  = 0; i &lt; current.length(); i++){
char c = current.charAt(i);
char temp  = c;
if( c == &#39;9&#39;){
c = &#39;0&#39;;
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 == &#39;0&#39;){
c = &#39;9&#39;;
}
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;
}
}

答案1

得分: 3

以下是翻译好的内容:

不太确定算法可能出了什么问题,我觉得看起来还挺好的,可能只是需要修复一些小问题。

几乎相同的方法,只是我们会在Java中使用三个集合(Sets)来解决这个问题:

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;
    }
}

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

参考资料:

  • 如需更多细节,请参阅讨论板块,在那里您可以找到许多解释详细的已通过解决方案,包括使用多种语言编写的低复杂度算法和渐近运行时间/内存分析12
英文:

Not really sure what might be wrong with your algorithm, looks pretty OK to me, might be something small that needs to be fixed.

Almost the same method, except we'd be using three Sets to solve the problem in Java:

public final class Solution {
public static final int openLock(
final String[] deadends,
final String target
) {
Set&lt;String&gt; startSet = new HashSet&lt;&gt;();
Set&lt;String&gt; endSet = new HashSet&lt;&gt;();
Set&lt;String&gt; deadSet = new HashSet&lt;&gt;(Arrays.asList(deadends));
startSet.add(&quot;0000&quot;);
endSet.add(target);
int minTurns = 0;
Set&lt;String&gt; tempSet;
while (!startSet.isEmpty() &amp;&amp; !endSet.isEmpty()) {
if (startSet.size() &gt; endSet.size()) {
tempSet = startSet;
startSet = endSet;
endSet = tempSet;
}
tempSet = new HashSet&lt;&gt;();
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 &lt; 4; i++) {
final char character = startSB.charAt(i);
String s1 = startSB.substring(0, i) + (character == &#39;9&#39; ? 0 : character - &#39;0&#39; + 1) + startSB.substring(i + 1);
String s2 = startSB.substring(0, i) + (character == &#39;0&#39; ? 9 : character - &#39;0&#39; - 1) + startSB.substring(i + 1);
if (!deadSet.contains(s1)) {
tempSet.add(s1);
}
if (!deadSet.contains(s2)) {
tempSet.add(s2);
}
}
}
minTurns++;
startSet = tempSet;
}
return -1;
}
}

OK! Here is LeetCode's BFS solution, based on which you can figure it out:

class Solution {
public int openLock(String[] deadends, String target) {
Set&lt;String&gt; dead = new HashSet();
for (String d: deadends) dead.add(d);
Queue&lt;String&gt; queue = new LinkedList();
queue.offer(&quot;0000&quot;);
queue.offer(null);
Set&lt;String&gt; seen = new HashSet();
seen.add(&quot;0000&quot;);
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 &lt; 4; ++i) {
for (int d = -1; d &lt;= 1; d += 2) {
int y = ((node.charAt(i) - &#39;0&#39;) + d + 10) % 10;
String nei = node.substring(0, i) + (&quot;&quot; + y) + node.substring(i+1);
if (!seen.contains(nei)) {
seen.add(nei);
queue.offer(nei);
}
}
}
}
}
return -1;
}
}

It seems that they have added new test cases for this problem.


References

  • For additional details, please see the 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 analysis<sup>1, 2</sup>.

答案2

得分: 0

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;
    }
}
英文:
 class Solution {
Queue&lt;String&gt; queue = new LinkedList&lt;String&gt;();
HashSet&lt;String&gt; deads = new HashSet&lt;String&gt;();
public int openLock(String[] deadends, String target) {
for(int i  = 0; i &lt; deadends.length; i++){
deads.add(deadends[i]);
}
if(deads.contains(&quot;0000&quot;))return -1;
int level  = bfs(&quot;0000&quot;, 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 &gt;0){
String current = queue.poll();
if(current.equals(target)) return level;
for(int i  = 0; i &lt; current.length(); i++){
char c = current.charAt(i);
char temp  = c;
if( c == &#39;9&#39;){
c = &#39;0&#39;;
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 == &#39;0&#39;){
c = &#39;9&#39;;
}
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;
}
}

huangapple
  • 本文由 发表于 2020年8月17日 08:18:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63443098.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定