编写“迷宫中的老鼠”问题的递归解决方案很困难

时间:2019-01-14 10:58:30

标签: java recursion

我的问题本质上是关于递归的疑问。我正在解决经典的“迷宫中的老鼠” DFS遍历问题。我的输入是一个n*n int数组a[][],其中对于索引ija[i][j]可以是010表示假设的老鼠无法访问该元素,而1意味着可以访问该元素。老鼠只能向下("D")或向右("R")走。任务是输出表示RDRDRD之类的所有运动字符串,它们代表大鼠在迷宫中的运动。老鼠从a[0][0]开始,必须到达a[n-1][n-1]。输入的是迷宫本身。

我写了以下代码

 public boolean isSafe(int x, int y, int[][] a, int n)
 {
    if(x >= 0 && x < n && y >= 0 && y < n && a[x][y] == 1)
        return true;
    else
        return false;
 }
 public ArrayList<String> printPath(int[][] a, int n)
 {
     ArrayList<String> res = new ArrayList<String>();
     solve(0,0,new String(), res,a,n);
     return res;
 }
 public void solve(int x, int y, String sol, ArrayList<String> res , 
 int[][]a, int n)
 {
     if(x == n-1 && y == n-1)
     {
         res.add(sol);
         return;
     }
     y++;
     if(isSafe(x,y,a,n))
     {
         solve(x,y,sol + "R",res,a,n);
     }
     else 
         y--;
     x++;
     if(isSafe(x,y,a,n))
     {
         solve(x,y,sol+"D",res,a,n);
     }
     else
         x--;
 }`

其中isSafe检查是否允许移动,printPath是用于打印输出的辅助函数,solve是用于遍历迷宫的递归函数。a将迷宫数组表示为二维数组。 对于输入

{1 0 0 0 
 1 1 0 1 
 0 1 0 0 
 0 1 1 1}

我得到以下输出

DRDDRR DDDRR

很明显,第二个字符串表示错误的结果。

但是,当我像这样更改solve函数时

public void solve(int x, int y, String sol, ArrayList<String> res, 
int[][]a, int n)
 {
    if(x == n-1 && y == n-1)
    {
        res.add(sol);
        return;
    }
    if(!isSafe(x,y,a,n))
       return;
    solve(x+1,y,sol + "D",res,a,n);
    solve(x,y+1,sol + "R",res,a,n);    
    return;  
 }

我得到正确的输出。我无法理解的是在我以前的解决方案中导致错误输出的原因,因为我认为这两种解决方案在逻辑上是相似的。 我知道这是一本很长的书,但是任何见解都将不胜感激。

2 个答案:

答案 0 :(得分:1)

在第一个解决方案中,仅当对具有递增值的y++的调用返回为负时,变量增量isSafe才被撤消,如果是,则继续进行x的检查。真正。这意味着将对具有有效相邻项右边的字段(特别是字段[1] [0])执行向下检查,而递增的值将是y,而不是正确的值。

如果您这样修改第一个解决方案

y++;
if(isSafe(x,y,a,n)){
    solve(x,y,sol + "R",res,a,n);
}
y--;

第一个解决方案将与第二个解决方案正常工作。在第二种解决方案中,增量仅在函数参数上完成,而不是在局部变量上完成。

答案 1 :(得分:1)

一般建议不要修改您的输入。在这种情况下,您的问题仅来自此。在这里,我修改了您的代码,所以它没有这样做。在我看来,它更具可读性,现在您可以确定要使用的x或y值。

if (isSafe(x, y + 1, a, n)) {
    solve(x, y + 1, sol + "R", res, a, n);
}
if (isSafe(x + 1, y, a, n)) {
    solve(x + 1, y, sol + "D", res, a, n);
}