📜  检查2D矩阵中可能的路径

📅  最后修改于: 2021-04-29 09:15:29             🧑  作者: Mango

给定2D数组(mxn)。任务是检查从左上角到右下角是否有任何路径。在矩阵中,-1被视为阻塞(无法通过此单元格),0被视为路径单元(可以通过此单元格)。

注意:左上方的单元格始终包含0

例子:

方法1

  • 方法:解决方案是执行BFS或DFS以查找是否存在路径。无需创建图形即可执行bfs,但矩阵本身将用作图形。从右上角开始遍历,如果有到达右下角的方法,则有一条路径。
  • 算法:
    1. 创建一个存储对(i,j)的队列,并将(0,0)插入该队列中。
    2. 循环运行直到队列为空。
    3. 在每次迭代中使队列(a,b)出队,如果最前面的元素是目的地(row-1,col-1),则返回1,即存在一条路径并更改mat [a] [b ]到-1,即已访问。
    4. 否则在矩阵[i] [j]的值不为-1的情况下插入相邻的索引。
  • 执行:
C++
// C++ program to find if there is path
// from top left to right bottom
#include 
using namespace std;
  
#define row 5
#define col 5
 
  
// to find the path from
// top left to bottom right
bool isPath(int arr[row][col])
{
    //directions
    int dir[4][2] = { {0,1}, {0,-1}, {1,0}, {-1,0}};
     
    //queue
    queue > q;
     
    //insert the top right corner.
    q.push(make_pair(0,0));
     
    //until queue is empty
    while(q.size()>0)
    {
        pair p = q.front();
        q.pop();
         
        //mark as visited
        arr[p.first][p.second] = -1;
         
        //destination is reached.
        if(p == make_pair(row-1,col-1))
            return true;
             
        //check all four directions
        for(int i=0; i<4 ;i++)
        {
            //using the direction array
            int a = p.first + dir[i][0];
            int b = p.second + dir[i][1];
             
            //not blocked and valid
            if(arr[a][b]!=-1&& a>=0 && b>=0
                    && a


Python3
# Python3 program to find if there is path
# from top left to right bottom
row = 5
col = 5
 
# to find the path from
# top left to bottom right
def isPath(arr) :
 
    # directions
    Dir = [ [0, 1], [0, -1], [1, 0], [-1, 0]]
     
    # queue
    q = []
     
    # insert the top right corner.
    q.append((0, 0))
     
    # until queue is empty
    while(len(q) > 0) :
        p = q[0]
        q.pop(0)
         
        # mark as visited
        arr[p[0]][p[1]] = -1
         
        # destination is reached.
        if(p == (row - 1, col - 1)) :
            return True
             
        # check all four directions
        for i in range(4) :
         
            # using the direction array
            a = p[0] + Dir[i][0]
            b = p[1] + Dir[i][1]
             
            # not blocked and valid
            if(a >= 0 and b >= 0 and a < row and b < col and arr[a][b] != -1) :           
                q.append((a, b))
    return False
   
# Given array
arr = [ [ 0, 0, 0, -1, 0 ],
        [ -1, 0, 0, -1, -1 ],
        [ 0, 0, 0, -1, 0 ],
        [ -1, 0, -1, 0, -1 ],
        [ 0, 0, -1, 0, 0 ] ]
 
# path from arr[0][0] to arr[row][col]
if (isPath(arr)) :
    print("Yes")
else :
    print("No")
 
    # This code is contributed by divyesh072019


C#
// C# program to find if there is path 
// from top left to right bottom
using System;
using System.Collections;
 
class GFG{
     
static int row = 5;
static int col = 5;
 
// To find the path from
// top left to bottom right
static bool isPath(int[,] arr)
{
     
    // Directions
    int[,] dir = { { 0, 1 }, { 0, -1 },
                   { 1, 0 }, { -1, 0 } };
       
    // Queue
    Queue q = new Queue();
     
    // Insert the top right corner.
    q.Enqueue(new Tuple(0, 0));
       
    // Until queue is empty
    while (q.Count > 0)
    {
        Tuple p = (Tuple)(q.Peek());
        q.Dequeue();
           
        // Mark as visited
        arr[p.Item1, p.Item2] = -1;
           
        // Destination is reached. 
        if (p == new Tuple(row - 1, col - 1))
            return true;
               
        // Check all four directions
        for(int i = 0; i < 4; i++)
        {
             
            // Using the direction array
            int a = p.Item1 + dir[i, 0];
            int b = p.Item2 + dir[i, 1];
               
            // Not blocked and valid
            if (a >= 0 && b >= 0 &&
               a < row && b < col &&
                  arr[a, b] != -1)
            {
                q.Enqueue(new Tuple(a, b));
            }
        }
    }
    return false;
}
 
// Driver Code
static void Main()
{
     
    // Given array
    int[,] arr = { { 0, 0, 0, -1, 0 },
                   { -1, 0, 0, -1, -1 },
                   { 0, 0, 0, -1, 0 },
                   { -1, 0, -1, 0, -1 },
                   { 0, 0, -1, 0, 0 } };
     
    // Path from arr[0][0] to arr[row][col]
    if (isPath(arr))
        Console.Write("Yes");
    else
        Console.Write("No");
}
}
 
// This code is contributed by divyeshrabadiya07


C++
// C++ program to find if there is path
// from top left to right bottom
#include 
using namespace std;
 
#define row 5
#define col 5
 
// to find the path from
// top left to bottom right
bool isPath(int arr[row][col])
{
    // set arr[0][0] = 1
    arr[0][0] = 1;
 
    // Mark reachable (from top left) nodes
    // in first row and first column.
    for (int i = 1; i < row; i++)
        if (arr[i][0] != -1)
            arr[i][0] = arr[i - 1][0];  
 
    for (int j = 1; j < col; j++)
        if (arr[0][j] != -1)
            arr[0][j] = arr[0][j - 1];   
 
    // Mark reachable nodes in remaining
    // matrix.
    for (int i = 1; i < row; i++)
        for (int j = 1; j < col; j++)
          if (arr[i][j] != -1)
              arr[i][j] = max(arr[i][j - 1],
                            arr[i - 1][j]);      
     
    // return yes if right bottom
    // index is 1
    return (arr[row - 1][col - 1] == 1);
}
 
// Driver Code
int main()
{
    // Given array
    int arr[row][col] = { { 0, 0, 0, -1, 0 },
                          { -1, 0, 0, -1, -1 },
                          { 0, 0, 0, -1, 0 },
                          { -1, 0, -1, 0, -1 },
                          { 0, 0, -1, 0, 0 } };
 
    // path from arr[0][0] to arr[row][col]
    if (isPath(arr))
      cout << "Yes";
    else
      cout << "No";
 
return 0;
}


Java
// Java program to find if there is path
// from top left to right bottom
class GFG
{
    // to find the path from
    // top left to bottom right
    static boolean isPath(int arr[][])
    {
        // set arr[0][0] = 1
        arr[0][0] = 1;
 
        // Mark reachable (from top left) nodes
        // in first row and first column.
        for (int i = 1; i < 5; i++)
            if (arr[0][i] != -1)
                arr[0][i] = arr[0][i - 1];
        for (int j = 1; j < 5; j++)
            if (arr[j][0] != -1)
                arr[j][0] = arr[j - 1][0];
 
        // Mark reachable nodes in
        //  remaining matrix.
        for (int i = 1; i < 5; i++)
            for (int j = 1; j < 5; j++)
                if (arr[i][j] != -1)
                    arr[i][j] = Math.max(arr[i][j - 1],
                                        arr[i - 1][j]);
 
        // return yes if right
        // bottom index is 1
        return (arr[5 - 1][5 - 1] == 1);
    }
      
    //Driver code
    public static void main(String[] args)
    {
        // Given array
        int arr[][] = { { 0, 0, 0, -1, 0 },
                        { -1, 0, 0, -1, -1 },
                        { 0, 0, 0, -1, 0 },
                        { -1, 0, -1, 0, -1 },
                        { 0, 0, -1, 0, 0 } };
 
        // path from arr[0][0]
        // to arr[row][col]
        if (isPath(arr))
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}
// This code is contributed
// by prerna saini


Python3
# Python3 program to find if there
# is path from top left to right bottom
row = 5
col = 5
 
# to find the path from
# top left to bottom right
def isPath(arr):
     
    # set arr[0][0] = 1
    arr[0][0] = 1
 
    # Mark reachable (from top left)
    # nodes in first row and first column.
    for i in range(1, row):
        if (arr[i][0] != -1):
            arr[i][0] = arr[i-1][0]
 
    for j in range(1, col):
        if (arr[0][j] != -1):
            arr[0][j] = arr[0][j-1]
             
    # Mark reachable nodes in
    # remaining matrix.
    for i in range(1, row):
        for j in range(1, col):
            if (arr[i][j] != -1):
                arr[i][j] = max(arr[i][j - 1],
                                arr[i - 1][j])
                                 
    # return yes if right
    # bottom index is 1
    return (arr[row - 1][col - 1] == 1)
 
# Driver Code
 
# Given array
arr = [[ 0, 0, 0, -1, 0 ],
       [-1, 0, 0, -1, -1],
       [ 0, 0, 0, -1, 0 ],
       [-1, 0, -1, 0, -1],
       [ 0, 0, -1, 0, 0 ]]
 
# path from arr[0][0] to arr[row][col]
if (isPath(arr)):
    print("Yes")
else:
    print("No")
 
# This code is contributed
# by sahilshelangia


C#
// C# program to find if there is path
// from top left to right bottom
using System;
 
class GFG
{
    // to find the path from
    // top left to bottom right
    static bool isPath(int [,]arr)
    {
        // set arr[0][0] = 1
        arr[0, 0] = 1;
 
        // Mark reachable (from top left) nodes
        // in first row and first column.
        for (int i = 1; i < 5; i++)
            if (arr[i, 0] != -1)
                arr[i, 0] = arr[i - 1, 0];
        for (int j = 1; j < 5; j++)
            if (arr[0,j] != -1)
                arr[0,j] = arr[0, j - 1];
 
        // Mark reachable nodes in
        // remaining matrix.
        for (int i = 1; i < 5; i++)
            for (int j = 1; j < 5; j++)
                if (arr[i, j] != -1)
                    arr[i, j] = Math.Max(arr[i, j - 1],
                                        arr[i - 1, j]);
 
        // return yes if right
        // bottom index is 1
        return (arr[5 - 1, 5 - 1] == 1);
    }
     
    //Driver code
    public static void Main()
    {
        // Given array
        int [,]arr = { { 0, 0, 0, -1, 0 },
                        { -1, 0, 0, -1, -1 },
                        { 0, 0, 0, -1, 0 },
                        { -1, 0, -1, 0, -1 },
                        { 0, 0, -1, 0, 0 } };
 
        // path from arr[0][0]
        // to arr[row][col]
        if (isPath(arr))
            Console.WriteLine("Yes");
        else
            Console.WriteLine("No");
    }
}
 
// This code is contributed
// by vt_m


PHP


Javascript


输出:

No
  • 复杂度分析:
    • 时间复杂度: O(R * C)。
      矩阵的每个元素都可以在队列中插入一次,因此时间复杂度为O(R * C)。
    • 空间复杂度: O(R * C)。
      要将所有元素存储在队列中,需要O(R * C)空间。

方法二

  • 方法:上述解决方案的唯一问题是它占用了额外的空间。这种方法将消除对额外空间的需求。基本思想非常相似。该算法也将执行BFS,但是通过标记阵列可以消除对额外空间的需求。因此,首先运行一个循环,并仅使用第一行和第一列,检查从0,0可访问第一列和第一行的哪些元素。将它们标记为1。现在以递增的行和列索引从行到行遍历矩阵。如果该信元未被阻塞,则检查其相邻信元中的任何一个是否标记为1。如果标记为1,则标记单元格1。
  • 算法:
    1. 将单元格0,0标记为1。
    2. 运行从0到行长的循环,如果上面的单元格标记为1并且当前单元格未被阻塞,则将当前单元格标记为1。
    3. 运行从0到列长的循环,如果左侧单元格标记为1并且当前单元格未被阻塞,则将当前单元格标记为1。
    4. 按行和列的递增索引从开始到结束逐行遍历矩阵。
    5. 如果该单元格未被阻塞,则检查其相邻的单元格中的任何一个(仅检查上方的单元格和左侧的单元格)。是否标记为1。如果标记为1,则标记单元格1。
    6. 如果单元格(行1,列1)标记为1,则返回true,否则返回false。
  • 执行:

C++

// C++ program to find if there is path
// from top left to right bottom
#include 
using namespace std;
 
#define row 5
#define col 5
 
// to find the path from
// top left to bottom right
bool isPath(int arr[row][col])
{
    // set arr[0][0] = 1
    arr[0][0] = 1;
 
    // Mark reachable (from top left) nodes
    // in first row and first column.
    for (int i = 1; i < row; i++)
        if (arr[i][0] != -1)
            arr[i][0] = arr[i - 1][0];  
 
    for (int j = 1; j < col; j++)
        if (arr[0][j] != -1)
            arr[0][j] = arr[0][j - 1];   
 
    // Mark reachable nodes in remaining
    // matrix.
    for (int i = 1; i < row; i++)
        for (int j = 1; j < col; j++)
          if (arr[i][j] != -1)
              arr[i][j] = max(arr[i][j - 1],
                            arr[i - 1][j]);      
     
    // return yes if right bottom
    // index is 1
    return (arr[row - 1][col - 1] == 1);
}
 
// Driver Code
int main()
{
    // Given array
    int arr[row][col] = { { 0, 0, 0, -1, 0 },
                          { -1, 0, 0, -1, -1 },
                          { 0, 0, 0, -1, 0 },
                          { -1, 0, -1, 0, -1 },
                          { 0, 0, -1, 0, 0 } };
 
    // path from arr[0][0] to arr[row][col]
    if (isPath(arr))
      cout << "Yes";
    else
      cout << "No";
 
return 0;
}

Java

// Java program to find if there is path
// from top left to right bottom
class GFG
{
    // to find the path from
    // top left to bottom right
    static boolean isPath(int arr[][])
    {
        // set arr[0][0] = 1
        arr[0][0] = 1;
 
        // Mark reachable (from top left) nodes
        // in first row and first column.
        for (int i = 1; i < 5; i++)
            if (arr[0][i] != -1)
                arr[0][i] = arr[0][i - 1];
        for (int j = 1; j < 5; j++)
            if (arr[j][0] != -1)
                arr[j][0] = arr[j - 1][0];
 
        // Mark reachable nodes in
        //  remaining matrix.
        for (int i = 1; i < 5; i++)
            for (int j = 1; j < 5; j++)
                if (arr[i][j] != -1)
                    arr[i][j] = Math.max(arr[i][j - 1],
                                        arr[i - 1][j]);
 
        // return yes if right
        // bottom index is 1
        return (arr[5 - 1][5 - 1] == 1);
    }
      
    //Driver code
    public static void main(String[] args)
    {
        // Given array
        int arr[][] = { { 0, 0, 0, -1, 0 },
                        { -1, 0, 0, -1, -1 },
                        { 0, 0, 0, -1, 0 },
                        { -1, 0, -1, 0, -1 },
                        { 0, 0, -1, 0, 0 } };
 
        // path from arr[0][0]
        // to arr[row][col]
        if (isPath(arr))
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}
// This code is contributed
// by prerna saini

Python3

# Python3 program to find if there
# is path from top left to right bottom
row = 5
col = 5
 
# to find the path from
# top left to bottom right
def isPath(arr):
     
    # set arr[0][0] = 1
    arr[0][0] = 1
 
    # Mark reachable (from top left)
    # nodes in first row and first column.
    for i in range(1, row):
        if (arr[i][0] != -1):
            arr[i][0] = arr[i-1][0]
 
    for j in range(1, col):
        if (arr[0][j] != -1):
            arr[0][j] = arr[0][j-1]
             
    # Mark reachable nodes in
    # remaining matrix.
    for i in range(1, row):
        for j in range(1, col):
            if (arr[i][j] != -1):
                arr[i][j] = max(arr[i][j - 1],
                                arr[i - 1][j])
                                 
    # return yes if right
    # bottom index is 1
    return (arr[row - 1][col - 1] == 1)
 
# Driver Code
 
# Given array
arr = [[ 0, 0, 0, -1, 0 ],
       [-1, 0, 0, -1, -1],
       [ 0, 0, 0, -1, 0 ],
       [-1, 0, -1, 0, -1],
       [ 0, 0, -1, 0, 0 ]]
 
# path from arr[0][0] to arr[row][col]
if (isPath(arr)):
    print("Yes")
else:
    print("No")
 
# This code is contributed
# by sahilshelangia

C#

// C# program to find if there is path
// from top left to right bottom
using System;
 
class GFG
{
    // to find the path from
    // top left to bottom right
    static bool isPath(int [,]arr)
    {
        // set arr[0][0] = 1
        arr[0, 0] = 1;
 
        // Mark reachable (from top left) nodes
        // in first row and first column.
        for (int i = 1; i < 5; i++)
            if (arr[i, 0] != -1)
                arr[i, 0] = arr[i - 1, 0];
        for (int j = 1; j < 5; j++)
            if (arr[0,j] != -1)
                arr[0,j] = arr[0, j - 1];
 
        // Mark reachable nodes in
        // remaining matrix.
        for (int i = 1; i < 5; i++)
            for (int j = 1; j < 5; j++)
                if (arr[i, j] != -1)
                    arr[i, j] = Math.Max(arr[i, j - 1],
                                        arr[i - 1, j]);
 
        // return yes if right
        // bottom index is 1
        return (arr[5 - 1, 5 - 1] == 1);
    }
     
    //Driver code
    public static void Main()
    {
        // Given array
        int [,]arr = { { 0, 0, 0, -1, 0 },
                        { -1, 0, 0, -1, -1 },
                        { 0, 0, 0, -1, 0 },
                        { -1, 0, -1, 0, -1 },
                        { 0, 0, -1, 0, 0 } };
 
        // path from arr[0][0]
        // to arr[row][col]
        if (isPath(arr))
            Console.WriteLine("Yes");
        else
            Console.WriteLine("No");
    }
}
 
// This code is contributed
// by vt_m

的PHP


Java脚本


输出:

No
  • 复杂度分析:
    • 时间复杂度: O(R * C)。
      遍历矩阵的每个元素,因此时间复杂度为O(R * C)。
    • 空间复杂度: O(1)。
      不需要额外的空间。