📜  具有障碍物的网格中的独特路径

📅  最后修改于: 2021-09-17 07:43:11             🧑  作者: Mango

给定一个大小为 m * n 的网格,让我们假设您从 (1, 1) 开始,您的目标是到达 (m, n)。在任何情况下,如果您在 (x, y) 上,您可以转到 (x, y + 1) 或 (x + 1, y)。
现在考虑是否在网格中添加了一些障碍物。会有多少条独特的路径?
障碍物和空白空间在网格中分别标记为 1 和 0。

例子:

Input: [[0, 0, 0],
        [0, 1, 0],
        [0, 0, 0]]
Output : 2
There is only one obstacle in the middle.

我们已经讨论了一个问题,当网格中没有障碍物时,计算网格中唯一路径的数量。但这里的情况完全不同。在穿过网格时,我们会遇到一些无法跳跃的障碍物,到达右下角的方式被阻止。
使用动态规划可以实现此问题的最有效解决方案。像每个动态问题概念一样,我们不会重新计算子问题。将构建一个临时的 2D 矩阵,并使用自下而上的方法存储值。

方法

  • 创建一个与给定矩阵大小相同的二维矩阵来存储结果。
  • 逐行遍历创建的数组并开始填充其中的值。
  • 如果发现障碍物,则将该值设置为 0。
  • 对于第一行和第一列,如果未找到障碍物,则将该值设置为 1。
  • 如果在给定矩阵中的相应位置不存在障碍物,则设置右侧和上限值的总和
  • 返回创建的二维矩阵的最后一个值
C++
// C++ code to find number of unique paths
// in a Matrix
#include
using namespace std;
 
int uniquePathsWithObstacles(vector>& A)
{
     
    int r = A.size(), c = A[0].size();
     
    // create a 2D-matrix and initializing
    // with value 0
    vector> paths(r, vector(c, 0));
     
    // Initializing the left corner if
    // no obstacle there
    if (A[0][0] == 0)
        paths[0][0] = 1;
         
    // Initializing first column of
    // the 2D matrix
    for(int i = 1; i < r; i++)
    {
        // If not obstacle
        if (A[i][0] == 0)
            paths[i][0] = paths[i-1][0];
    }
     
    // Initializing first row of the 2D matrix
    for(int j = 1; j < c; j++)
    {
         
        // If not obstacle
        if (A[0][j] == 0)
            paths[0][j] = paths[0][j - 1];
    }  
      
    for(int i = 1; i < r; i++)
    {
        for(int j = 1; j < c; j++)
        {
             
            // If current cell is not obstacle
            if (A[i][j] == 0)
                paths[i][j] = paths[i - 1][j] +
                              paths[i][j - 1];
        } 
    }
     
    // Returning the corner value
    // of the matrix
    return paths[r - 1];
}
 
// Driver code
int main()
{
   vector> A = { { 0, 0, 0 },
                             { 0, 1, 0 },
                             { 0, 0, 0 } };
                              
   cout << uniquePathsWithObstacles(A) << " \n";                                               
}
 
// This code is contributed by ajaykr00kj


Java
// Java code to find number of unique paths
// in a Matrix
public class Main
{
  static int uniquePathsWithObstacles(int[][] A)
  {
 
    int r = 3, c = 3;
 
    // create a 2D-matrix and initializing
    // with value 0
    int[][] paths = new int[r];
    for(int i = 0; i < r; i++)
    {
      for(int j = 0; j < c; j++)
      {
        paths[i][j] = 0;
      }
    }
 
    // Initializing the left corner if
    // no obstacle there
    if (A[0][0] == 0)
      paths[0][0] = 1;
 
    // Initializing first column of
    // the 2D matrix
    for(int i = 1; i < r; i++)
    {
      // If not obstacle
      if (A[i][0] == 0)
        paths[i][0] = paths[i - 1][0];
    }
 
    // Initializing first row of the 2D matrix
    for(int j = 1; j < c; j++)
    {
 
      // If not obstacle
      if (A[0][j] == 0)
        paths[0][j] = paths[0][j - 1];
    }  
 
    for(int i = 1; i < r; i++)
    {
      for(int j = 1; j < c; j++)
      {
 
        // If current cell is not obstacle
        if (A[i][j] == 0)
          paths[i][j] = paths[i - 1][j] +
          paths[i][j - 1];
      } 
    }
 
    // Returning the corner value
    // of the matrix
    return paths[r - 1];
  }
 
  // Driver code
  public static void main(String[] args) {
    int[][] A = { { 0, 0, 0 },
                 { 0, 1, 0 },
                 { 0, 0, 0 } };
 
    System.out.print(uniquePathsWithObstacles(A));
  }
}
 
// This code is contributed by divyeshrabadiya07.


Python
# Python code to find number of unique paths in a
# matrix with obstacles.
 
def uniquePathsWithObstacles(A):
 
    # create a 2D-matrix and initializing with value 0
    paths = [[0]*len(A[0]) for i in A]
     
    # initializing the left corner if no obstacle there
    if A[0][0] == 0:
        paths[0][0] = 1
     
    # initializing first column of the 2D matrix
    for i in range(1, len(A)):
         
        # If not obstacle
        if A[i][0] == 0:
            paths[i][0] = paths[i-1][0]
             
    # initializing first row of the 2D matrix
    for j in range(1, len(A[0])):
         
        # If not obstacle
        if A[0][j] == 0:
            paths[0][j] = paths[0][j-1]
             
    for i in range(1, len(A)):
        for j in range(1, len(A[0])):
 
            # If current cell is not obstacle
            if A[i][j] == 0:
                paths[i][j] = paths[i-1][j] + paths[i][j-1]
 
    # returning the corner value of the matrix
    return paths[-1][-1]
 
 
# Driver Code
A = [[0, 0, 0], [0, 1, 0], [0, 0, 0]]
print(uniquePathsWithObstacles(A))


C#
// C# code to find number of unique paths
// in a Matrix
using System;
class GFG {
 
  static int uniquePathsWithObstacles(int[,] A)
  {
 
    int r = 3, c = 3;
 
    // create a 2D-matrix and initializing
    // with value 0
    int[,] paths = new int[r,c];
    for(int i = 0; i < r; i++)
    {
      for(int j = 0; j < c; j++)
      {
        paths[i, j] = 0;
      }
    }
 
    // Initializing the left corner if
    // no obstacle there
    if (A[0, 0] == 0)
      paths[0, 0] = 1;
 
    // Initializing first column of
    // the 2D matrix
    for(int i = 1; i < r; i++)
    {
      // If not obstacle
      if (A[i, 0] == 0)
        paths[i, 0] = paths[i - 1, 0];
    }
 
    // Initializing first row of the 2D matrix
    for(int j = 1; j < c; j++)
    {
 
      // If not obstacle
      if (A[0, j] == 0)
        paths[0, j] = paths[0, j - 1];
    }  
 
    for(int i = 1; i < r; i++)
    {
      for(int j = 1; j < c; j++)
      {
 
        // If current cell is not obstacle
        if (A[i, j] == 0)
          paths[i, j] = paths[i - 1, j] +
          paths[i, j - 1];
      } 
    }
 
    // Returning the corner value
    // of the matrix
    return paths[r - 1, c - 1];
  }
 
  // Driver code
  static void Main() {
    int[,] A = { { 0, 0, 0 },
                { 0, 1, 0 },
                { 0, 0, 0 } };
 
    Console.WriteLine(uniquePathsWithObstacles(A));
  }
}
 
// This code is contributed by divyesh072019.


Javascript


C++
// CPP program for the above approach
 
#include 
using namespace std;
 
int uniquePathsWithObstacles(vector >& A)
{
 
    int r = A.size();
    int c = A[0].size();
 
    // If obstacle is at starting position
    if (A[0][0])
        return 0;
 
    //  Initializing starting position
    A[0][0] = 1;
 
    // first row all are '1' until obstacle
    for (int j = 1; j < c; j++) {
 
        if (A[0][j] == 0) {
            A[0][j] = A[0][j - 1];
        }
        else {
            // No ways to reach at this index
            A[0][j] = 0;
        }
    }
 
    // first column all are '1' until obstacle
    for (int i = 1; i < r; i++) {
 
        if (A[i][0] == 0) {
            A[i][0] = A[i - 1][0];
        }
        else {
            // No ways to reach at this index
            A[i][0] = 0;
        }
    }
 
    for (int i = 1; i < r; i++) {
 
        for (int j = 1; j < c; j++) {
            // If current cell has no obstacle
            if (A[i][j] == 0) {
 
                A[i][j] = A[i - 1][j] + A[i][j - 1];
            }
            else {
                // No ways to reach at this index
                A[i][j] = 0;
            }
        }
    }
 
    // returing the bottom right
    // corner of Grid
    return A[r - 1];
}
 
// Driver Code
 
int main()
{
 
    vector > A
        = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };
 
    cout << uniquePathsWithObstacles(A) << "\n";
 
    return 0;
}
// This code is contributed by hemantraj712


输出
2 

DP 解决方案的空间优化。

在这种方法中,我们将使用给定的 ‘A’ 2D 矩阵使用自下而上的方法存储先前的答案。

方法

  • 开始逐行遍历给定的 ‘A’ 2D 矩阵并填充其中的值。
  • 如果未找到障碍物,则将第一行和第一列的值设置为 1。
  • 对于第一行和第一列,如果发现障碍,则开始填充 0 直到该特定行或列中的最后一个索引。
  • 现在从第二行和第二列开始遍历(例如:A[1][1])。
  • 如果找到障碍物,则在特定网格处设置 0(例如:A[ i ][ j ] ),否则在 A[ i ][ j ] 处设置上值和左值的总和。
  • 返回二维矩阵的最后一个值。

下面是上述方法的实现。

C++

// CPP program for the above approach
 
#include 
using namespace std;
 
int uniquePathsWithObstacles(vector >& A)
{
 
    int r = A.size();
    int c = A[0].size();
 
    // If obstacle is at starting position
    if (A[0][0])
        return 0;
 
    //  Initializing starting position
    A[0][0] = 1;
 
    // first row all are '1' until obstacle
    for (int j = 1; j < c; j++) {
 
        if (A[0][j] == 0) {
            A[0][j] = A[0][j - 1];
        }
        else {
            // No ways to reach at this index
            A[0][j] = 0;
        }
    }
 
    // first column all are '1' until obstacle
    for (int i = 1; i < r; i++) {
 
        if (A[i][0] == 0) {
            A[i][0] = A[i - 1][0];
        }
        else {
            // No ways to reach at this index
            A[i][0] = 0;
        }
    }
 
    for (int i = 1; i < r; i++) {
 
        for (int j = 1; j < c; j++) {
            // If current cell has no obstacle
            if (A[i][j] == 0) {
 
                A[i][j] = A[i - 1][j] + A[i][j - 1];
            }
            else {
                // No ways to reach at this index
                A[i][j] = 0;
            }
        }
    }
 
    // returing the bottom right
    // corner of Grid
    return A[r - 1];
}
 
// Driver Code
 
int main()
{
 
    vector > A
        = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };
 
    cout << uniquePathsWithObstacles(A) << "\n";
 
    return 0;
}
// This code is contributed by hemantraj712
输出
2

时间复杂度: O(m*n)
辅助空间: O(1)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程