我必须生成一个5 x 5矩阵,随机值为0和1。
在这样的矩阵中,我必须找到从左到右存在由1组成的路径。相邻的1可以是垂直的,水平的或对角相邻的(也称为8连接)。
成功案例的一个例子是
1 0 0 1 0
0 1 0 1 1
1 1 1 1 0
0 0 0 1 0
1 1 0 1 1
我已经生成了矩阵,并且发现很难确定路径。
我想到检查每个上/下/右/对角线索引= 1的值并继续前进。但在这种情况下,我不知道如何保持一条道路。
任何解决方案/算法都会非常有用。
答案 0 :(得分:3)
修改强> 编辑修复了上一代码中的错误。从本质上讲,它会跟踪以前访问过的节点,以避免回溯,并在所有方向上搜索可能的其他路径。
使用受访节点,它还会跟踪经过的实际路径。
public static boolean hasPathHelper(int[][] m, int[][] v, int i, int j){
if(i < 0 || j < 0 || i >= m.length || j >= m[0].length || v[i][j] >= 0)
return false; // Index out of bounds
v[i][j] = 0; // Mark as visited
if(m[i][j] == 0) // Path stops here
return false;
if(j == m[0].length - 1 || // Right side reached!
hasPathHelper(m, v, i - 1, j + 1) || // Check upper right
hasPathHelper(m, v, i + 1, j + 1) || // Check lower right
hasPathHelper(m, v, i + 1, j - 1) || // Check lower left
hasPathHelper(m, v, i + 1, j - 1) || // Check upper left
hasPathHelper(m, v, i + 1, j ) || // Check down
hasPathHelper(m, v, i - 1, j ) || // Check up
hasPathHelper(m, v, i , j + 1) || // Check right
hasPathHelper(m, v, i , j - 1) // Check left
) v[i][j] = 1; // Mark as good path
return v[i][j] == 1;
}
public static boolean hasPath(int[][] m, int[][] v){
for(int i = 0; i < m.length; i++)
if(hasPathHelper(m, v, i, 0))
return true;
return false;
}
public static void main(String... args){
int[][] m = { {0,1,1,1,0},
{1,0,0,1,0},
{0,0,1,1,0},
{0,1,0,0,0},
{0,0,1,1,1} };
int[][] v = new int[5][5]; // v => -1, not visited
for(int i=0; i<5; i++) // v => 0, visited bad path
Arrays.fill(v[i], -1); // v => 1, visited good path
System.out.println("Has Path?: " + hasPath(m, v));
System.out.println("Path Matrix: ");
for(int i = 0; i < v.length; i++)
System.out.println(Arrays.toString(v[i]));
}
Has Path?: true
Path Matrix:
[ 0, 1, 1, -1, 0]
[ 1, 0, 0, 1, -1]
[-1, -1, 1, -1, 0]
[-1, 1, 0, 0, 0]
[-1, -1, 1, 1, 1]
答案 1 :(得分:0)
递归是你的朋友(伪):
boolean existsPath(field, from, to)
{
if (field[from] == 0) return false;
if (from == to) return true;
if (existsPath(field, from + up, to)) return true;
if (existsPath(field, from + down, to)) return true;
if (existsPath(field, from + right, to)) return true;
if (existsPath(field, from + diag, to)) return true;
return false;
}
粗略地说,这样的事情会对你有所帮助。 您需要额外检查,以防止您在同一时间来两次。
答案 2 :(得分:0)
您应该查看Graph Traversal算法。深度优先搜索可能最容易实现。我不会给你代码,所以你可以学到一些东西。到目前为止提交的所有三个都不是完全正确的。
在您的情况下,DFS将如下所示(在伪代码中):
search(i, j, path)
if [i,j] is off the matrix, return null
return null if a[i,j] already marked;
if j == 3, return path
mark a[i,j]
new_path = path :: <i,j> // append the pair <i,j> on the path list
return search(i + 1, j + 1) unless its value is null
return search(i + 1, j) unless its value is null
return search(i + 1, j - 1) unless its value is null
return search(i - 1, j + 1) unless its value is null
return search(i - 1, j) unless its value is null
return search(i - 1, j - 1) unless its value is null
return search(i, j + 1) unless its value is null
return search(i, j - 1)
标记搜索路径的一种简单方法是将所有1改为-1或类似的东西。
答案 3 :(得分:0)
构造一个2D访问boolean
数组,其中包含与输入数组大小相同的所有false
值。
现在检查输入数组每行的第一个单元格
如果该单元格为1
且未设置相应的访问单元格:
Stack
。1
的所有未访问的邻居添加到堆栈中。这也应该相当容易递归(但递归函数的高级描述稍微困难一些)。