在递归中查找迷宫中的多种方式

时间:2013-02-16 20:02:28

标签: c# algorithm non-recursive

给定一个矩阵[n,n]我想知道我们可以通过非递归方式从[0,0]到[n,n]达到多少种方式。

我的方法是

  1. 创建一个stuct节点来存储到目前为止行进的行,列和路径
  2. 将节点添加到队列
  3. 通过队列迭代直到不空。增量行,增量列。添加到队列
  4. 如果row = n,col = n
  5. ,则打印路径

    问题

    1. 是否有不同的存储行,列和路径的方式
    2. 如果n非常大,则在队列中存储节点可能会出现问题。我们怎样才能避免这种情况?
    3. 请不要我不是在寻找递归解决方案。 我在很多面试论坛上都看到了这样的问题,所以想知道这是否是正确的方法。

      以下是Node的结构和功能

       struct Node
          {
              public int row;
              public int col;
              public string path;
      
              public Node(int r, int c, string p)
              {
                  this.row = r;
                  this.col = c;
                  this.path = p;
              }
          }
      
      
      
      
       public static void NextMoveNonRecursive(int max)
          {
      
              int rowPos;
              int colPos;
              string prevPath = "";
              Node next;
      
              while (qu.Count > 0)
              {
                  Node current = qu.Dequeue();
                  rowPos = current.row;
                  colPos = current.col;
                  prevPath = current.path;
      
                  if (rowPos + 1 == max && colPos + 1 == max)
                  {
                      Console.WriteLine("Path = ..." + prevPath);
                      TotalPathCounter++;
                  }
      
                  if (rowPos + 1 < max)
                  {
                      if (prevPath == "")
                          prevPath = current.path;
      
                      prevPath = prevPath + ">" + (rowPos + 1) + "" + (colPos);
                      next = new Node(rowPos + 1, colPos, prevPath);
                      qu.Enqueue(next);
                      prevPath = "";
                  }
      
                  if (colPos + 1 < max)
                  {
      
                      if (prevPath == "")
                          prevPath = current.path;
      
                      prevPath = prevPath + ">" + (rowPos) + "" + (colPos+1);
                      next = new Node(rowPos, colPos+1, prevPath);
                      qu.Enqueue(next);
                      prevPath = "";
                  }
      
              }
          }
      

3 个答案:

答案 0 :(得分:3)

dp[i, j][0, 0][i, j]的路径数。

我们有:

dp[0, i] = dp[i, 0] = 1 for all i = 0 to n
dp[i, j] = dp[i - 1, j] +     come down from all paths to [i - 1, j]
           dp[i, j - 1] +     come down from all paths to [i, j - 1]         
           dp[i - 1, j - 1]   come down from all paths to [i - 1, j - 1] 
           for i, j > 0

如果无法同时增加行和列,请从上述总和中删除dp[i - 1, j - 1]

dp[n, n]会有你的答案。

答案 1 :(得分:1)

给定一个矩阵[n,n],我们可以通过增加一个col或一行来从[0,0]到[n,n]达到多少种方式?

(n*2-2) choose (n*2-2)/2

如果你只能向下或向右(即增加行或列),它似乎是一个二元命题 - 我们可以将'向下'或'向右'视为'0'或'1'。

在nxn矩阵中,跟随右/右条件的每条路径的长度都是n * 2-2(例如,在3x3平方中,路径总是长度为4;在4x4方格中,长度为6)。 / p>

x和1的二进制数的总组合数是2 ^ x。在这种情况下,我们的'x'是n * 2-2,但我们不能使用所有组合,因为'down'或'right'的数量不能超过n-1。似乎我们需要所有具有相同数字0和1的二进制组合。解决方案是...... tada

(n*2-2) choose (n*2-2)/2

在Haskell中,您可以编写以下非递归函数来列出路径:

import Data.List
mazeWays n = nub $ permutations $ concat $ replicate ((n*2-2) `div` 2) "DR"

如果你想要路径数,那么:

length $ mazeWays n

答案 2 :(得分:0)

带示例的Javascript解决方案

var arr = [
    [1, 1, 1, 0, 0, 1, 0],
    [1, 0, 1, 1, 1, 1, 0],
    [1, 0, 1, 0, 1, 0, 0],
    [1, 1, 0, 0, 1, 0, 0],
    [1, 0, 0, 0, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1]
];

function sols2(arr){
    var h = arr.length,
            w = arr[0].length,
            i, j, current, left, top;

    for(i = 0; i < h; i++){
        for(j = 0; j < w; j++){
            current = arr[i][j];
            top = i === 0 ? 0.5 : arr[i - 1][j];
            left = j === 0 ? 0.5 : arr[i][j-1];

            if(left === 0 && top === 0){
                arr[i][j] = 0;
            } else if(current > 0 && (left > 0 || top > 0)){
                arr[i][j] = (left + top) | 0;
            } else {
                console.log('a6');
                arr[i][j] = 0;
            }       
        }
    }
    return arr[h-1][w-1];
}

sols2(arr);