获取迷宫中的所有路径(仅水平/垂直移动)

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

Get all Paths (Horizontal/Vertical Moves Only) in a Maze

问题

class Result {
  
    public static List<String> getSafePaths(int n) {
        List<String> paths = new ArrayList<>();
 
        int er = n - 1;
        int ec = n - 1;
        int[][] matrix = new int[n][n]; 
        matrix[0][0] = 2;

        getPaths(matrix, 0, 0, er, ec, paths, "");

        return paths;
    }
    
    public static void getPaths(int[][] matrix, int sr, int sc, int er, int ec, List<String> paths, String s) {
        if(sr == er && sc == ec) {
            paths.add(new String(s));
        }
        
        final int[][] SHIFTS = {
            {0, 1}, // go right
            {1, 0}  // go down
        };
        
        for(int[] shift : SHIFTS) {
            int right = -1;
            int down = -1;
            
            if(shift[0] == 0) {
                right = 1;
            }
            else {
                down = 1;
            }
            
            String letter = valid(matrix, sr + shift[0], sc + shift[1], right, down);
            if(letter != null) {
                
                if(letter.equals("H")) {
                    s = s + "H";
                }
                if(letter.equals("V")) {
                    s = s + "V";
                }
              
                matrix[sr + shift[0]][sc + shift[1]] = 2;
                
                getPaths(matrix, sr + shift[0], sc + shift[1], er, ec, paths, s);
            } 
        }
    }
    
    public static String valid(int[][] matrix, int sr, int sc, int right, int down) {
        if(sr >= 0 && sr < matrix.length && sc >= 0 && sc < matrix[sr].length && matrix[sr][sc] != 2) {
            if(right == 1) {
                return "H";
            }
            else {
                return "V";
            }
        }
        return null;
    }
}

请注意,我已经根据你的要求,将代码翻译并返回。如果你有任何进一步的问题或需要解释,请随时提问。

英文:

I'm trying to find all the paths in the maze where the only valid moves are going right ("H") or doing down ("V"). I want to return a list of strings of these paths.

My code currently does not return a list of these strings and I think the error is in trying to using the same String object to build the answer recursively. If anyone could help me fix that (or any other errors they might see) I would really appreciate it!

I considered making a Coordinate class, is this the right approach? If so, I'm not sure how to use this class to make the proper string. This is what I thought the class could look like:

 public static class Coordinate {
public int row, col;
public String path;
public Coordinate (int row, int col) {
this.row = row;
this.col = col;
path = new String();
}
public addLetter(String s) {
path = path + s;
}
}

An example of what the question is asking, if my matrix is of size 3:

 0  1 2 
0 X H H
1     V
2     V
0  1 2 
0 X H 
1   V H
2     V
0  1 2 
0 X H 
1   V
2   V H
0  1 2 
0 X 
1 V H H
2     V
0  1 2 
0 X 
1 V H 
2   V H
0  1 2 
0 X 
1 V  
2 V H H
And all the possible strings are:
- HHVV, HVHV, HVVH, VHHV, VHVH, VVHH

So if the input n is equal to 3, the function should return a list of strings ["HHVV", "HVHV", "HVVH", "VHHV", "VHVH", "VVHH"].

If the input n is 2, the function should return:
["HV", "VH"].

class Result {
public static List&lt;String&gt; getSafePaths(int n) {
//do a dfs on the graph
List&lt;String&gt; paths = new ArrayList&lt;&gt;();
int er = n - 1;
int ec = n - 1;
int[][] matrix = new int[n][n]; 
matrix[0][0] = 2; //all visited nodes changed to two
getPaths(matrix, 0, 0, er, ec, paths, &quot;&quot;);
return paths;
}
public static void getPaths(int[][] matrix, int sr, int sc, int er, int ec, List&lt;String&gt; paths, String s) {
if(sr == er &amp;&amp; sc == ec) {
paths.add(new String(s));
}
final int[][] SHIFTS = {
{0, 1}, //go right
{1,0} // go down
};
for(int[] shift : SHIFTS) {
int right = -1;
int down = -1;
//are we going down or right? Need this to add correct letter
if(shift[0] == 0) {
right = 1;
}
else {
down = 1;
}
String letter = valid(matrix, sr + shift[0], sc + shift[1], right, down);
if(letter != null) {
if(letter == &quot;H&quot;) {
s = s + &quot;H&quot;;
}
if(letter == &quot;V&quot;) {
s = s + &quot;V&quot;;
}
matrix[sr + shift[0]][sc + shift[1]] = 2;
getPaths(matrix, sr + shift[0], sc + shift[1], er, ec, paths, s);
} 
}
}
public static String valid(int[][] matrix, int sr, int sc, int right, int down) {
if(sr &gt;= 0 &amp;&amp; sr &lt; matrix.length &amp;&amp; sc &gt;= 0 &amp;&amp; sc &lt; matrix[sr].length &amp;&amp; matrix[sr][sc] != 2) {
if(right == 1) {
return &quot;H&quot;;
}
else {
return &quot;V&quot;;
}
}
return null;
}
}

答案1

得分: 1

主要问题(但肯定不是唯一的问题)是标记已访问的位置(通过将matrix的值设置为2来标记)。
一旦一个位置被标记为2,后续的搜索就不能将该位置包含在路径中。
以目标位置为例。在到达目标位置后,它会被标记为2,这意味着后续的搜索无法再到达它。这就是为什么paths在搜索完成时只包含一条路径。
实际上,在这种情况下,根本不需要标记已访问的位置。唯一可能的移动方式是向下和向右,因此搜索不会两次返回相同的位置。
只需将matrix[currentRow + shift[0]][currentColumn + shift[1]] = 2;注释掉即可获得更多的路径(并揭示更多的错误)。


附注:

/* 通过letter.equals("H")检查字符串之间的相等性
if(letter == "H") {
s = s + "H";
}
if(letter == "V") {
s = s + "V";
}
*/

// 这两个if块是不需要的。letter只能是V或H,所以可以简单地执行:
s = s + letter; // 或者 s += letter 或者 s = s.concat(letter)

英文:

The main issue (but certainly not the only one) is the marking of visited position (it is marked by setting the value of matrix to 2.). </br>
Once a position is marked by 2, the following searches can not include this position in the path.</br>
Think of the target position for example. After it has been reached, it is marked by 2 which means no following search can get to it anymore. This is why paths contain only one path when search is completed. </br>
In fact, in this case marking visited position is not needed at all. The only possible movements are down and right, so the search can not return to the same position twice. <br/>
Simply comment out matrix[currentRow + shift[0]][currentColumn + shift[1]] = 2; to get more paths (and reveal more bugs).

<hr>
Side note:

			/* check for equality  between strings by letter.equals(&quot;H&quot;)
if(letter == &quot;H&quot;) {
s = s + &quot;H&quot;;
}
if(letter == &quot;V&quot;) {
s = s + &quot;V&quot;;
}
*/
//the two if blocks are not needed. letter can only be V or H so simply do:
s=s+letter;  //or s+=letter  or s=s.concat(letter) 

huangapple
  • 本文由 发表于 2020年10月19日 12:40:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/64421254.html
匿名

发表评论

匿名网友

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

确定