【发布时间】:2014-12-13 05:02:18
【问题描述】:
所以我正在尝试制定一种算法来查找 NxN 网格中的完整路径。例如,在 1x1 网格中有 1 条可能的路径,在 2x2 网格中有 1 条,在 3x3 中有 2 条,在 4x4 中有 8 条。我们的想法是找到我们可以通过移动来填充网格的每个点的场景。
我为这个工作做了一个递归函数,代码如下:
public static int getRoutesHelp(int[][] table, int x, int y)
{
if(x > table.length-1 || x < 0 || y < 0 || y > table.length-1)
return 0;
if(table[x][y] == 1)
return 0;
table[x][y] = 1;
if(isDeadEnd(table, x, y))
{
if(isTableFull(table))
return 1;
}
else
{
int a = getRoutesHelp(table, x-1, y);
int d = getRoutesHelp(table, x, y+1);
int b = getRoutesHelp(table, x+1, y);
int c = getRoutesHelp(table, x, y-1);
return a+b+c+d;
}
return 0;
}
public static int getRoutes(int size)
{
int[][] table = new int[size][size];
// init table
for(int i = 0; i < size; i++)
{
for(int a = 0; a < size; a++)
{
table[i][a] = 0;
}
}
return getRoutesHelp(table, 0 ,0);
}
所以基本上我从 0.0 开始并开始移动到所有可能的方向,通过重复这个我得到成功路线的数量。问题是在分配int d 之后,原始表以某种方式填充了1,但据我了解它应该是空的,因为java 传递了表的副本,对吗?我已经为此奋斗了 4 个小时,但无法真正找到问题所在,因此不胜感激。表中的空槽用 0 标记,填充槽用 1 标记。
编辑:我设法解决了我在复制时遇到的问题,现在我的另一个问题是,对于 5x5 网格,我的算法返回 52 条路线,它应该是 86。所以它适用于 4x4 网格好的,但是一旦我进一步移动它就会中断。
在此处添加了 isDeadEnd 函数
public static boolean isDeadEnd(int[][] table, int x, int y)
{
int toCheck[] = new int[4];
toCheck[0] = x-1; // left
toCheck[1] = y-1; // top
toCheck[2] = x+1; // right
toCheck[3] = y+1; // bottom
int valuesOfDirections[] = new int[4]; // left, top, right, bottom
for(int i = 0; i < 4; i++)
{
int tarkastettava = toCheck[i];
if(tarkastettava > table.length-1 || tarkastettava < 0)
{
valuesOfDirections[i] = 1;
}
else
{
if(i == 0 || i == 2)
{
valuesOfDirections[i] = table[tarkastettava][y];
}
else
{
valuesOfDirections[i] = table[x][tarkastettava];
}
}
}
for(int i = 0; i < 4; i++)
{
if(valuesOfDirections[i] == 0)
{
return false;
}
}
return true;
}
【问题讨论】:
-
数组是引用类型。因此,您的表格只有一份副本。要修复您的代码,您需要在从递归返回之前添加
table[x][y] = 0 -
我在传递表格时也尝试使用 .clone() 但同样的事情发生了。我应该怎么做才能防止这种情况发生?
-
克隆从未真正奏效。你必须复制你的桌子。如果管理得当,则递归级别不应超过一个副本。否则可以考虑回溯。
-
我用自己的函数完全克隆解决了克隆问题。
-
图论在这里应该有所帮助