【问题标题】:Recursion with 2 dimensional array二维数组递归
【发布时间】:2014-02-17 08:41:19
【问题描述】:

我正在编写一个递归方法来查找二维数组中的所有可能路径。从左上点 (0,0) 到右下点最后一个点。并返回路径的总和。

public static void printPathWeights(int[][] m)
{
    printPathWeights(m, 0, 0, 0);
}

public static void printPathWeights(int[][] m, int row, int col, int sum)
{
    if(row == 0 && col ==0)
    sum = 0;

    if (row == m.length - 1 && col == m[row].length - 1)
        System.out.println(sum);

    else
    {
        if (row >= 0 && row < m.length && col >= 0 && col < m[row].length)
        printPathWeights(m, row - 1, col, sum += m[row][col]); // Up
        if (row >= 0 && row < m.length && col >= 0 && col < m[row].length)
            printPathWeights(m, row + 1, col, sum += m[row][col]); // Down
        if (row >= 0 && row < m.length && col >= 0 && col < m[row].length)
            printPathWeights(m, row, col - 1, sum += m[row][col]); // Left
        if (row >= 0 && row < m.length && col >= 0 && col < m[row].length)
            printPathWeights(m, row, col + 1, sum += m[row][col]); // Right
    }
}

目前我的问题是这个函数进入无限循环并且不打印我的总和

【问题讨论】:

  • 给你这个任务的人可能参与了上周的 Hackerrank.com CodeSprint 5 竞赛。这是他们提出的问题之一:)

标签: java recursion


【解决方案1】:

我认为它被困在:

if (row >= 0 && row < m.length && col >= 0 && col < m[row].length)
        printPathWeights(m, row, col - 1, sum += m[row][col]); // Left
if (row >= 0 && row < m.length && col >= 0 && col < m[row].length)
        printPathWeights(m, row, col + 1, sum += m[row][col]); // Right

它会不断地来回跳跃。

而且,正如 Miquel 所指出的,为什么路径不能上升?

解决方案:(假设路径不能相互交叉,否则总和会变为无穷大)

  • 跟踪您去过的地方。将该历史记录传递给下一次递归。

  • 将您所在的图块的值添加到作为参数传递的总和值中。

  • 如果您已经完成,请打印总和。

  • 其他: 尝试朝四个可能的方向前进。如果那个方向没有单元格,这将失败,即你处于边缘。如果您已经去过那里,它也会失败。

  • 如果你不能在任何地方移动,即你被卡住了,你什么都不做就返回。

【讨论】:

  • 我需要改变什么来修复它?
  • 我用解决方案更新了我的答案。它可能还有一些缺陷,但它是一个开始的地方。
  • 如果我在终点,为什么要返回 1 ?
  • 因为你刚刚找到了一条可能的路径。调用者方法会将该值添加到其他方向返回的值中,然后依次返回。
  • 我想返回传递的总和,例如路径在值为 1、2、4 的单元格中,所以我需要返回 7
【解决方案2】:

您需要将单元格标记为已访问,否则您的算法将使您永远在同一行左右移动。还有,你怎么也上不去?

【讨论】:

    【解决方案3】:
    public static void printPathWeights(int [][] m) 
     { 
    printPathWeights (m, 0, 0, 0); 
     } 
    
     private static void printPathWeights(int [][]m, int i, int j,int sum) 
    { 
     if (i<0 || i>=m.length || j<0 || j>=m[0].length) 
     return; 
     if (m[i][j] == -1) 
     return; 
     if (i==m.length-1 && j==m[0].length-1) 
     System.out.println (sum + m[m.length-1][m[0].length-1]); 
     int temp = m[i][j]; 
     m[i][j] = -1; 
     printPathWeights (m, i+1, j, sum+temp); 
     printPathWeights (m, i, j+1, sum+temp); 
     printPathWeights (m, i-1, j, sum+temp); 
     printPathWeights (m, i, j-1, sum+temp); 
     m[i][j] = temp; 
      }
    

    试试这个,你把 -1 放在你之前已经去过的地方,然后折叠你放回数字,为下一条路径做好准备

    【讨论】:

      【解决方案4】:

      完整的工作代码。已测试...

      public static void printPathWeights(int [][] m) {

          printPathWeights( m, 0, 0, 0, 0 );
      

      }

      //1 - 如果右单元格清晰,2 - 如果左单元格清晰,0 - 中性

      private static int printPathWeights(int[][] m, int sum, int flag, int row, int col) {

          if ( row == m.length - 1 && col == m[0].length - 1 ){
              System.out.print( (sum + m[row][col]) + "  " );
              return sum;
          }
      
          //Check if the RIGHT cell legal - (That's to say current cell was not called by the rigth cell
          // and the boundry is legal)
          if( flag != 1 && ((col+1) <= m[0].length - 1) )
              printPathWeights( m, sum + m[row][col], 2, row, col + 1 );
      
          //Check if the DONN/Below cell is legal - (That is to say the boundry is legal. We do not check
          // if we came from below cell since we do not have 'UP' call)
          if( ((row+1) <= m.length - 1) )
              printPathWeights( m, sum + m[row][col], 0, row + 1, col ); 
      
          //Check if the LEFT cell legal - (That's to say current cell was not called by the LEFT cell
          // and the boundry is legal and if We are at the top level we DO NOT TURN LEFT)
          if( flag != 2 && ((col - 1) >= 0) && row != m.length - 1 )
              printPathWeights( m, sum + m[row][col], 1, row, col - 1 );
      
         return sum;
      
      }
      

      【讨论】:

        猜你喜欢
        • 2013-01-01
        • 2019-07-27
        • 1970-01-01
        • 2017-08-05
        • 2018-06-24
        • 1970-01-01
        • 2016-07-13
        • 2012-11-19
        相关资源
        最近更新 更多