📌  相关文章
📜  查找矩阵中两个单元格之间是否存在路径

📅  最后修改于: 2022-05-13 01:57:21.428000             🧑  作者: Mango

查找矩阵中两个单元格之间是否存在路径

给定填充有 1、0、2、3 的 NXN 矩阵。查找是否存在从源到目的地的可能路径,仅遍历空白单元格。您可以向上、向下、向右和向左移动。

  • 单元格1的值表示源。
  • 单元格2的值表示目的地。
  • 单元格3的值表示空白单元格。
  • 单元格0的值表示空白墙。

注意:只有一个源和一个目的地(接收器)。

例子:

提问:Adobe 面试

简单的解决方案:递归。
方法:在每个矩阵中找到单元格的源索引,然后在矩阵中递归地找到从源索引到目标的路径。该算法涉及递归查找所有路径,直到找到到达目的地的最终路径。

算法 :

  1. 遍历矩阵并找到矩阵的起始索引。
  2. 创建一个接受索引和访问矩阵的递归函数。
  3. 标记当前单元格并检查当前单元格是否为目的地。如果当前单元格是目标,则返回 true。
  4. 为所有相邻的空单元格和未访问的单元格调用递归函数。
  5. 如果任何递归函数返回 true,则取消标记单元格并返回 true,否则取消标记单元格并返回 false。
C++
// C++ program to find path between two
// cell in matrix
#include 
using namespace std;
#define N 4
 
// Method for checking boundaries
bool isSafe(int i, int j, int matrix[][N])
{
  if (i >= 0 && i < N && j >= 0 && j < N)
    return true;
  return false;
}
 
// Returns true if there is a
// path from a source (a
// cell with value 1) to a
// destination (a cell with
// value 2)
bool isPath(int matrix[][N], int i, int j,
            bool visited[][N])
{
  // Checking the boundaries, walls and
  // whether the cell is unvisited
  if (isSafe(i, j, matrix) && matrix[i][j] != 0
      && !visited[i][j])
  {
    // Make the cell visited
    visited[i][j] = true;
 
    // if the cell is the required
    // destination then return true
    if (matrix[i][j] == 2)
      return true;
 
    // traverse up
    bool up = isPath(matrix, i - 1, j, visited);
 
    // if path is found in up
    // direction return true
    if (up)
      return true;
 
    // traverse left
    bool left = isPath(matrix, i, j - 1, visited);
 
    // if path is found in left
    // direction return true
    if (left)
      return true;
 
    // traverse down
    bool down = isPath(matrix, i + 1, j, visited);
 
    // if path is found in down
    // direction return true
    if (down)
      return true;
 
    // traverse right
    bool right = isPath(matrix, i, j + 1, visited);
 
    // if path is found in right
    // direction return true
    if (right)
      return true;
  }
 
  // no path has been found
  return false;
}
 
// Method for finding and printing
// whether the path exists or not
void isPath(int matrix[][N])
{
 
  // Defining visited array to keep
  // track of already visited indexes
  bool visited[N][N];
 
  // Flag to indicate whether the
  // path exists or not
  bool flag = false;
  for (int i = 0; i < N; i++)
  {
    for (int j = 0; j < N; j++)
    {
      // if matrix[i][j] is source
      // and it is not visited
      if (matrix[i][j] == 1 && !visited[i][j])
 
        // Starting from i, j and
        // then finding the path
        if (isPath(matrix, i, j, visited))
        {
 
          // if path exists
          flag = true;
          break;
        }
    }
  }
  if (flag)
    cout << "YES";
  else
    cout << "NO";
}
 
// Driver program to
// check above function
int main()
{
  int matrix[N][N] = { { 0, 3, 0, 1 },
                      { 3, 0, 3, 3 },
                      { 2, 3, 3, 3 },
                      { 0, 3, 3, 3 } };
 
  // calling isPath method
  isPath(matrix);
  return 0;
}
 
// This code is contributed by sudhanshugupta2019a.


Java
// Java program to find path between two
// cell in matrix
class Path {
 
    // Method for finding and printing
    // whether the path exists or not
    public static void isPath(
        int matrix[][], int n)
    {
        // Defining visited array to keep
        // track of already visited indexes
        boolean visited[][]
            = new boolean[n][n];
 
        // Flag to indicate whether the
        // path exists or not
        boolean flag = false;
 
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                // if matrix[i][j] is source
                // and it is not visited
                if (
                    matrix[i][j] == 1
                    && !visited[i][j])
 
                    // Starting from i, j and
                    // then finding the path
                    if (isPath(
                            matrix, i, j, visited)) {
                        // if path exists
                        flag = true;
                        break;
                    }
            }
        }
        if (flag)
            System.out.println("YES");
        else
            System.out.println("NO");
    }
 
    // Method for checking boundaries
    public static boolean isSafe(
        int i, int j,
        int matrix[][])
    {
 
        if (
            i >= 0 && i < matrix.length
            && j >= 0
            && j < matrix[0].length)
            return true;
        return false;
    }
 
    // Returns true if there is a
    // path from a source (a
    // cell with value 1) to a
    // destination (a cell with
    // value 2)
    public static boolean isPath(
        int matrix[][],
        int i, int j,
        boolean visited[][])
    {
 
        // Checking the boundaries, walls and
        // whether the cell is unvisited
        if (
            isSafe(i, j, matrix)
            && matrix[i][j] != 0
            && !visited[i][j]) {
            // Make the cell visited
            visited[i][j] = true;
 
            // if the cell is the required
            // destination then return true
            if (matrix[i][j] == 2)
                return true;
 
            // traverse up
            boolean up = isPath(
                matrix, i - 1,
                j, visited);
 
            // if path is found in up
            // direction return true
            if (up)
                return true;
 
            // traverse left
            boolean left
                = isPath(
                    matrix, i, j - 1, visited);
 
            // if path is found in left
            // direction return true
            if (left)
                return true;
 
            // traverse down
            boolean down = isPath(
                matrix, i + 1, j, visited);
 
            // if path is found in down
            // direction return true
            if (down)
                return true;
 
            // traverse right
            boolean right
                = isPath(
                    matrix, i, j + 1,
                    visited);
 
            // if path is found in right
            // direction return true
            if (right)
                return true;
        }
        // no path has been found
        return false;
    }
 
    // driver program to
    // check above function
    public static void main(String[] args)
    {
 
        int matrix[][] = { { 0, 3, 0, 1 },
                           { 3, 0, 3, 3 },
                           { 2, 3, 3, 3 },
                           { 0, 3, 3, 3 } };
 
        // calling isPath method
        isPath(matrix, 4);
    }
}
 
/* This code is contributed by Madhu Priya */


Python3
# Python3 program to find
# path between two cell in matrix
 
# Method for finding and printing
# whether the path exists or not
def isPath(matrix, n):
 
    # Defining visited array to keep
    # track of already visited indexes
    visited = [[False for x in range (n)]
                      for y in range (n)]
    
    # Flag to indicate whether the
    # path exists or not
    flag = False
 
    for i in range (n):
        for j in range (n):
           
            # If matrix[i][j] is source
            # and it is not visited
            if (matrix[i][j] == 1 and not
                visited[i][j]):
 
                # Starting from i, j and
                # then finding the path
                if (checkPath(matrix, i,
                              j, visited)):
                   
                    # If path exists
                    flag = True
                    break
    if (flag):
        print("YES")
    else:
        print("NO")
 
# Method for checking boundaries
def isSafe(i, j, matrix):
   
    if (i >= 0 and i < len(matrix) and
        j >= 0 and j < len(matrix[0])):
        return True
    return False
 
# Returns true if there is a
# path from a source(a
# cell with value 1) to a
# destination(a cell with
# value 2)
def checkPath(matrix, i, j,
              visited):
 
    # Checking the boundaries, walls and
    # whether the cell is unvisited
    if (isSafe(i, j, matrix) and
        matrix[i][j] != 0 and not
        visited[i][j]):
       
        # Make the cell visited
        visited[i][j] = True
 
        # If the cell is the required
        # destination then return true
        if (matrix[i][j] == 2):
           return True
 
        # traverse up
        up = checkPath(matrix, i - 1,
                       j, visited)
 
        # If path is found in up
        # direction return true
        if (up):
           return True
 
        # Traverse left
        left = checkPath(matrix, i,
                         j - 1, visited)
 
        # If path is found in left
        # direction return true
        if (left):
           return True
 
        # Traverse down
        down = checkPath(matrix, i + 1,
                         j, visited)
 
        # If path is found in down
        # direction return true
        if (down):
           return True
 
        # Traverse right
        right = checkPath(matrix, i,
                          j + 1, visited)
 
        # If path is found in right
        # direction return true
        if (right):
           return True
     
    # No path has been found
    return False
 
# Driver code
if __name__ == "__main__":
   
    matrix = [[0, 3, 0, 1],
              [3, 0, 3, 3],
              [2, 3, 3, 3],
              [0, 3, 3, 3]]
 
    # calling isPath method
    isPath(matrix, 4)
 
# This code is contributed by Chitranayal


C#
// C# program to find path between two
// cell in matrix
using System;
 
class GFG{
 
// Method for finding and printing
// whether the path exists or not
static void isPath(int[,] matrix, int n)
{
     
    // Defining visited array to keep
    // track of already visited indexes
    bool[,] visited = new bool[n, n];
     
    // Flag to indicate whether the
    // path exists or not
    bool flag = false;
 
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
             
            // If matrix[i][j] is source
            // and it is not visited
            if (matrix[i, j] == 1 &&
              !visited[i, j])
               
                // Starting from i, j and
                // then finding the path
                if (isPath(matrix, i, j,
                           visited))
                {
                     
                    // If path exists
                    flag = true;
                    break;
                }
        }
    }
    if (flag)
        Console.WriteLine("YES");
    else
        Console.WriteLine("NO");
}
 
// Method for checking boundaries
public static bool isSafe(int i, int j,
                          int[,] matrix)
{
    if (i >= 0 && i < matrix.GetLength(0) &&
        j >= 0 && j < matrix.GetLength(1))
        return true;
         
    return false;
}
 
// Returns true if there is a path from
// a source (a cell with value 1) to a
// destination (a cell with value 2)
public static bool isPath(int[,] matrix, int i,
                          int j, bool[,] visited)
{
     
    // Checking the boundaries, walls and
    // whether the cell is unvisited
    if (isSafe(i, j, matrix) &&
           matrix[i, j] != 0 &&
         !visited[i, j])
    {
         
        // Make the cell visited
        visited[i, j] = true;
 
        // If the cell is the required
        // destination then return true
        if (matrix[i, j] == 2)
            return true;
 
        // Traverse up
        bool up = isPath(matrix, i - 1,
                         j, visited);
 
        // If path is found in up
        // direction return true
        if (up)
            return true;
 
        // Traverse left
        bool left = isPath(matrix, i,
                           j - 1, visited);
 
        // If path is found in left
        // direction return true
        if (left)
            return true;
 
        // Traverse down
        bool down = isPath(matrix, i + 1,
                           j, visited);
 
        // If path is found in down
        // direction return true
        if (down)
            return true;
 
        // Traverse right
        bool right = isPath(matrix, i, j + 1,
                            visited);
 
        // If path is found in right
        // direction return true
        if (right)
            return true;
    }
     
    // No path has been found
    return false;
}
 
// Driver code  
static void Main()
{
    int[,] matrix = { { 0, 3, 0, 1 },
                      { 3, 0, 3, 3 },
                      { 2, 3, 3, 3 },
                      { 0, 3, 3, 3 } };
 
    // Calling isPath method
    isPath(matrix, 4);
}
}
 
// This code is contributed by divyeshrabadiya07


Javascript


C++
// C++ program to find path
// between two cell in matrix
#include 
using namespace std;
#define N 4
 
class Graph {
    int V;
    list* adj;
 
public:
    Graph(int V)
    {
        this->V = V;
        adj = new list[V];
    }
    void addEdge(int s, int d);
    bool BFS(int s, int d);
};
 
// add edge to graph
void Graph::addEdge(int s, int d)
{
    adj[s].push_back(d);
}
 
// BFS function to find path
// from source to sink
bool Graph::BFS(int s, int d)
{
    // Base case
    if (s == d)
        return true;
 
    // Mark all the vertices as not visited
    bool* visited = new bool[V];
    for (int i = 0; i < V; i++)
        visited[i] = false;
 
    // Create a queue for BFS
    list queue;
 
    // Mark the current node as visited and
    // enqueue it
    visited[s] = true;
    queue.push_back(s);
 
    // it will be used to get all adjacent
    // vertices of a vertex
    list::iterator i;
 
    while (!queue.empty()) {
        // Dequeue a vertex from queue
        s = queue.front();
        queue.pop_front();
 
        // Get all adjacent vertices of the
        // dequeued vertex s. If a adjacent has
        // not been visited, then mark it visited
        // and enqueue it
        for (
            i = adj[s].begin(); i != adj[s].end(); ++i) {
            // If this adjacent node is the
            // destination node, then return true
            if (*i == d)
                return true;
 
            // Else, continue to do BFS
            if (!visited[*i]) {
                visited[*i] = true;
                queue.push_back(*i);
            }
        }
    }
 
    // If BFS is complete without visiting d
    return false;
}
 
bool isSafe(int i, int j, int M[][N])
{
    if (
        (i < 0 || i >= N)
        || (j < 0 || j >= N)
        || M[i][j] == 0)
        return false;
    return true;
}
 
// Returns true if there is
// a path from a source (a
// cell with value 1) to a
// destination (a cell with
// value 2)
bool findPath(int M[][N])
{
    // source and destination
    int s, d;
    int V = N * N + 2;
    Graph g(V);
 
    // create graph with n*n node
    // each cell consider as node
    // Number of current vertex
    int k = 1;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (M[i][j] != 0) {
                // connect all 4 adjacent
                // cell to current cell
                if (isSafe(i, j + 1, M))
                    g.addEdge(k, k + 1);
                if (isSafe(i, j - 1, M))
                    g.addEdge(k, k - 1);
                if (i < N - 1 && isSafe(i + 1, j, M))
                    g.addEdge(k, k + N);
                if (i > 0 && isSafe(i - 1, j, M))
                    g.addEdge(k, k - N);
            }
 
            // Source index
            if (M[i][j] == 1)
                s = k;
 
            // Destination index
            if (M[i][j] == 2)
                d = k;
            k++;
        }
    }
 
    // find path Using BFS
    return g.BFS(s, d);
}
 
// driver program to check
// above function
int main()
{
    int M[N][N] = { { 0, 3, 0, 1 },
                    { 3, 0, 3, 3 },
                    { 2, 3, 3, 3 },
                    { 0, 3, 3, 3 } };
 
    (findPath(M) == true) ? cout << "Yes" : cout << "No" << endl;
 
    return 0;
}


Java
// Java program to find path between two
// cell in matrix
import java.util.*;
 
class Graph {
    int V;
    List > adj;
 
    Graph(int V)
    {
        this.V = V;
        adj = new ArrayList<>(V);
        for (int i = 0; i < V; i++) {
            adj.add(i, new ArrayList<>());
        }
    }
 
    // add edge to graph
    void addEdge(int s, int d)
    {
        adj.get(s).add(d);
    }
 
    // BFS function to find path
    // from source to sink
    boolean BFS(int s, int d)
    {
        // Base case
        if (s == d)
            return true;
 
        // Mark all the vertices as not visited
        boolean[] visited = new boolean[V];
 
        // Create a queue for BFS
        Queue queue
            = new LinkedList<>();
 
        // Mark the current node as visited and
        // enqueue it
        visited[s] = true;
        queue.offer(s);
 
        // it will be used to get all adjacent
        // vertices of a vertex
        List edges;
 
        while (!queue.isEmpty()) {
            // Dequeue a vertex from queue
            s = queue.poll();
 
            // Get all adjacent vertices of the
            // dequeued vertex s. If a adjacent has
            // not been visited, then mark it visited
            // and enqueue it
            edges = adj.get(s);
            for (int curr : edges) {
                // If this adjacent node is the
                // destination node, then return true
                if (curr == d)
                    return true;
 
                // Else, continue to do BFS
                if (!visited[curr]) {
                    visited[curr] = true;
                    queue.offer(curr);
                }
            }
        }
 
        // If BFS is complete without visiting d
        return false;
    }
 
    static boolean isSafe(
        int i, int j, int[][] M)
    {
        int N = M.length;
        if (
            (i < 0 || i >= N)
            || (j < 0 || j >= N)
            || M[i][j] == 0)
            return false;
        return true;
    }
 
    // Returns true if there is a
    // path from a source (a
    // cell with value 1) to a
    // destination (a cell with
    // value 2)
    static boolean findPath(int[][] M)
    {
        // Source and destination
        int s = -1, d = -1;
        int N = M.length;
        int V = N * N + 2;
        Graph g = new Graph(V);
 
        // Create graph with n*n node
        // each cell consider as node
        int k = 1; // Number of current vertex
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (M[i][j] != 0) {
 
                    // connect all 4 adjacent
                    // cell to current cell
                    if (isSafe(i, j + 1, M))
                        g.addEdge(k, k + 1);
                    if (isSafe(i, j - 1, M))
                        g.addEdge(k, k - 1);
                    if (i < N - 1
                        && isSafe(i + 1, j, M))
                        g.addEdge(k, k + N);
                    if (i > 0 && isSafe(i - 1, j, M))
                        g.addEdge(k, k - N);
                }
 
                // source index
                if (M[i][j] == 1)
                    s = k;
 
                // destination index
                if (M[i][j] == 2)
                    d = k;
                k++;
            }
        }
 
        // find path Using BFS
        return g.BFS(s, d);
    }
 
    // Driver program to check above function
    public static void main(
        String[] args) throws Exception
    {
        int[][] M = { { 0, 3, 0, 1 },
                      { 3, 0, 3, 3 },
                      { 2, 3, 3, 3 },
                      { 0, 3, 3, 3 } };
 
        System.out.println(
            ((findPath(M)) ? "Yes" : "No"));
    }
}
 
// This code is contributed by abhay379201


Python3
# Python3 program to find path between two
# cell in matrix
from collections import defaultdict
class Graph:
    def __init__(self):
        self.graph = defaultdict(list)
     
    # add edge to graph
    def addEdge(self, u, v):
        self.graph[u].append(v)
 
    # BFS function to find path from source to sink    
    def BFS(self, s, d):
         
        # Base case
        if s == d:
            return True
             
        # Mark all the vertices as not visited
        visited = [False]*(len(self.graph) + 1)
 
        # Create a queue for BFS
        queue = []
        queue.append(s)
 
        # Mark the current node as visited and
        # enqueue it
        visited[s] = True
        while(queue):
 
            # Dequeue a vertex from queue
            s = queue.pop(0)
 
            # Get all adjacent vertices of the
            # dequeued vertex s. If a adjacent has
            # not been visited, then mark it visited
            # and enqueue it
            for i in self.graph[s]:
                 
                # If this adjacent node is the destination
                # node, then return true
                if i == d:
                    return True
 
                # Else, continue to do BFS
                if visited[i] == False:
                    queue.append(i)
                    visited[i] = True
 
        # If BFS is complete without visiting d
        return False
 
def isSafe(i, j, matrix):
    if i >= 0 and i <= len(matrix) and j >= 0 and j <= len(matrix[0]):
        return True
    else:
        return False
 
# Returns true if there is a path from a source (a
# cell with value 1) to a destination (a cell with
# value 2)
def findPath(M):
    s, d = None, None # source and destination
    N = len(M)
    g = Graph()
 
    # create graph with n * n node
    # each cell consider as node
    k = 1 # Number of current vertex
    for i in range(N):
        for j in range(N):
            if (M[i][j] != 0):
 
                # connect all 4 adjacent cell to
                # current cell
                if (isSafe(i, j + 1, M)):
                    g.addEdge(k, k + 1)
                if (isSafe(i, j - 1, M)):
                    g.addEdge(k, k - 1)
                if (isSafe(i + 1, j, M)):
                    g.addEdge(k, k + N)
                if (isSafe(i - 1, j, M)):
                    g.addEdge(k, k - N)
             
            if (M[i][j] == 1):
                s = k
 
            # destination index    
            if (M[i][j] == 2):
                d = k
            k += 1
 
    # find path Using BFS
    return g.BFS(s, d)
 
# Driver code
if __name__=='__main__':
    M =[[0, 3, 0, 1], [3, 0, 3, 3], [2, 3, 3, 3], [0, 3, 3, 3]]
    if findPath(M):
        print("Yes")
    else:
        print("No")
 
# This Code is Contributed by Vikash Kumar 37


Javascript


C++
#include 
#include 
using namespace std;
#define R 4
#define C 4
 
// Structure to define a vertex u=(i,j)
typedef struct BFSElement {
    BFSElement(int i, int j)
    {
        this->i = i;
        this->j = j;
    }
    int i;
    int j;
} BFSElement;
 
bool findPath(int M[R][C])
{
    // 1) Create BFS queue q
    queue q;
 
    // 2)scan the matrix
    for (int i = 0; i < R; ++i) {
        for (int j = 0; j < C; ++j) {
           
            // if there exists a cell in the matrix such
            // that its value is 1 then push it to q
            if (M[i][j] == 1) {
                q.push(BFSElement(i, j));
                break;
            }
        }
    }
   
    // 3) run BFS algorithm with q.
    while (!q.empty()) {
        BFSElement x = q.front();
        q.pop();
        int i = x.i;
        int j = x.j;
       
        // skipping cells which are not valid.
        // if outside the matrix bounds
        if (i < 0 || i > R || j < 0 || j > C)
            continue;
       
        // if they are walls (value is 0).
        if (M[i][j] == 0)
            continue;
 
        // 3.1) if in the BFS algorithm process there was a
        // vertex x=(i,j) such that M[i][j] is 2 stop and
        // return true
        if (M[i][j] == 2)
            return true;
       
        // marking as wall upon successful visitation
        M[i][j] = 0;
 
        // pushing to queue u=(i,j+1),u=(i,j-1)
        //                 u=(i+1,j),u=(i-1,j)
        for (int k = -1; k <= 1; k += 2) {
            q.push(BFSElement(i + k, j));
            q.push(BFSElement(i, j + k));
        }
    }
   
    // BFS algorithm terminated without returning true
    // then there was no element M[i][j] which is 2, then
    // return false
    return false;
}
 
// Main Driver code
int main()
{
 
    int M[R][C] = { { 0, 3, 0, 1 },
                    { 3, 0, 3, 3 },
                    { 2, 3, 3, 3 },
                    { 0, 3, 3, 3 } };
 
    (findPath(M) == true) ? cout << "Yes"
                          : cout << "No" << endl;
 
    return 0;
}


Java
import java.io.*;
import java.util.*;
 
class BFSElement
{
    int i, j;
    BFSElement(int i, int j)
    {
        this.i = i;
        this.j = j;
    }
}
 
class GFG {
    static int R = 4, C = 4;
    BFSElement b;
     
    static boolean findPath(int M[][])
    {
       
        // 1) Create BFS queue q
        Queue q = new LinkedList<>();
       
        // 2)scan the matrix
        for (int i = 0; i < R; ++i)
        {
            for (int j = 0; j < C; ++j)
            {
                
                // if there exists a cell in the matrix such
                // that its value is 1 then push it to q
                if (M[i][j] == 1) {
                    q.add(new BFSElement(i, j));
                    break;
                }
            }
         
        }
     
        // 3) run BFS algorithm with q.
        while (q.size() != 0)
        {
            BFSElement x = q.peek();
            q.remove();
            int i = x.i;
            int j = x.j;
           
            // skipping cells which are not valid.
            // if outside the matrix bounds
            if (i < 0 || i >= R || j < 0 || j >= C)
                continue;
            
            // if they are walls (value is 0).
            if (M[i][j] == 0)
                continue;
      
            // 3.1) if in the BFS algorithm process there was a
            // vertex x=(i,j) such that M[i][j] is 2 stop and
            // return true
            if (M[i][j] == 2)
                return true;
            
            // marking as wall upon successful visitation
            M[i][j] = 0;
      
            // pushing to queue u=(i,j+1),u=(i,j-1)
            // u=(i+1,j),u=(i-1,j)
            for (int k = -1; k <= 1; k += 2)
            {
                q.add(new BFSElement(i + k, j));
                q.add(new BFSElement(i, j + k));
            }
        }
             
        // BFS algorithm terminated without returning true
        // then there was no element M[i][j] which is 2, then
        // return false
        return false;
     
    }
   
    // Main Driver code
    public static void main (String[] args)
    {
        int M[][] = { { 0, 3, 0, 1 },
                    { 3, 0, 3, 3 },
                    { 2, 3, 3, 3 },
                    { 0, 3, 3, 3 } };
         
        if(findPath(M) == true)
            System.out.println("Yes");
        else
            System.out.println("No");     
    }
}
 
// This code is contributed by avanitrachhadiya2155


C#
using System;
using System.Collections.Generic;
 
public class BFSElement
{
  public int i, j;
  public BFSElement(int i, int j)
  {
    this.i = i;
    this.j = j;
  }
}
 
public class GFG
{   
  static int R = 4, C = 4;  
  static bool findPath(int[,] M)
  {
 
    // 1) Create BFS queue q
    Queue q = new Queue();
 
    // 2)scan the matrix
    for (int i = 0; i < R; ++i)
    {
      for (int j = 0; j < C; ++j)
      {
 
        // if there exists a cell in the matrix such
        // that its value is 1 then push it to q
        if (M[i, j] == 1) {
          q.Enqueue(new BFSElement(i, j));
          break;
        }
      }
 
    }
 
    // 3) run BFS algorithm with q.
    while (q.Count != 0)
    {
      BFSElement x = q.Peek();
      q.Dequeue();
      int i = x.i;
      int j = x.j;
 
      // skipping cells which are not valid.
      // if outside the matrix bounds
      if (i < 0 || i >= R || j < 0 || j >= C)
        continue;
 
      // if they are walls (value is 0).
      if (M[i, j] == 0)
        continue;
 
      // 3.1) if in the BFS algorithm process there was a
      // vertex x=(i,j) such that M[i][j] is 2 stop and
      // return true
      if (M[i, j] == 2)
        return true;
 
      // marking as wall upon successful visitation
      M[i, j] = 0;
 
      // pushing to queue u=(i,j+1),u=(i,j-1)
      // u=(i+1,j),u=(i-1,j)
      for (int k = -1; k <= 1; k += 2)
      {
        q.Enqueue(new BFSElement(i + k, j));
        q.Enqueue(new BFSElement(i, j + k));
      }
    }
 
    // BFS algorithm terminated without returning true
    // then there was no element M[i][j] which is 2, then
    // return false
    return false;
 
  }
 
  // Main Driver code
  static public void Main (){
    int[,] M = { { 0, 3, 0, 1 },
                { 3, 0, 3, 3 },
                { 2, 3, 3, 3 },
                { 0, 3, 3, 3 } };
 
    if(findPath(M) == true)
      Console.WriteLine("Yes");
    else
      Console.WriteLine("No");  
  }
}
 
// This code is contributed by rag2127


Javascript


输出
YES

复杂性分析:

  • 时间复杂度: O(4 n*m )。
    对于每个单元格,可以有 4 个相邻的未访问单元格,因此时间复杂度为 O(4 n*m )。
  • 空间复杂度: O(n*m)。
    存储访问的数组需要空间。

有效的解决方案:图表。
方法:这个想法是使用广度优先搜索。将每个单元格视为一个节点,任何两个相邻单元格之间的每个边界都是一条边。所以Node的总数是N * N。
所以想法是从起始单元格开始进行广度优先搜索,直到找到结束单元格。

算法:

  1. 创建一个具有 N*N 节点(顶点)的空 Graph,将所有节点推入一个图中,并记下源和汇顶点。
  2. 现在在图上应用 BFS,创建一个队列并将源节点插入队列中
  3. 循环运行直到队列的大小大于 0
  4. 移除队列的前端节点,如果destination返回true,则检查该节点是否为destination。标记节点
  5. 如果未访问,则检查所有相邻单元格,并将它们空白插入队列中。
  6. 如果未到达目的地,则返回 true。

C++

// C++ program to find path
// between two cell in matrix
#include 
using namespace std;
#define N 4
 
class Graph {
    int V;
    list* adj;
 
public:
    Graph(int V)
    {
        this->V = V;
        adj = new list[V];
    }
    void addEdge(int s, int d);
    bool BFS(int s, int d);
};
 
// add edge to graph
void Graph::addEdge(int s, int d)
{
    adj[s].push_back(d);
}
 
// BFS function to find path
// from source to sink
bool Graph::BFS(int s, int d)
{
    // Base case
    if (s == d)
        return true;
 
    // Mark all the vertices as not visited
    bool* visited = new bool[V];
    for (int i = 0; i < V; i++)
        visited[i] = false;
 
    // Create a queue for BFS
    list queue;
 
    // Mark the current node as visited and
    // enqueue it
    visited[s] = true;
    queue.push_back(s);
 
    // it will be used to get all adjacent
    // vertices of a vertex
    list::iterator i;
 
    while (!queue.empty()) {
        // Dequeue a vertex from queue
        s = queue.front();
        queue.pop_front();
 
        // Get all adjacent vertices of the
        // dequeued vertex s. If a adjacent has
        // not been visited, then mark it visited
        // and enqueue it
        for (
            i = adj[s].begin(); i != adj[s].end(); ++i) {
            // If this adjacent node is the
            // destination node, then return true
            if (*i == d)
                return true;
 
            // Else, continue to do BFS
            if (!visited[*i]) {
                visited[*i] = true;
                queue.push_back(*i);
            }
        }
    }
 
    // If BFS is complete without visiting d
    return false;
}
 
bool isSafe(int i, int j, int M[][N])
{
    if (
        (i < 0 || i >= N)
        || (j < 0 || j >= N)
        || M[i][j] == 0)
        return false;
    return true;
}
 
// Returns true if there is
// a path from a source (a
// cell with value 1) to a
// destination (a cell with
// value 2)
bool findPath(int M[][N])
{
    // source and destination
    int s, d;
    int V = N * N + 2;
    Graph g(V);
 
    // create graph with n*n node
    // each cell consider as node
    // Number of current vertex
    int k = 1;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (M[i][j] != 0) {
                // connect all 4 adjacent
                // cell to current cell
                if (isSafe(i, j + 1, M))
                    g.addEdge(k, k + 1);
                if (isSafe(i, j - 1, M))
                    g.addEdge(k, k - 1);
                if (i < N - 1 && isSafe(i + 1, j, M))
                    g.addEdge(k, k + N);
                if (i > 0 && isSafe(i - 1, j, M))
                    g.addEdge(k, k - N);
            }
 
            // Source index
            if (M[i][j] == 1)
                s = k;
 
            // Destination index
            if (M[i][j] == 2)
                d = k;
            k++;
        }
    }
 
    // find path Using BFS
    return g.BFS(s, d);
}
 
// driver program to check
// above function
int main()
{
    int M[N][N] = { { 0, 3, 0, 1 },
                    { 3, 0, 3, 3 },
                    { 2, 3, 3, 3 },
                    { 0, 3, 3, 3 } };
 
    (findPath(M) == true) ? cout << "Yes" : cout << "No" << endl;
 
    return 0;
}

Java

// Java program to find path between two
// cell in matrix
import java.util.*;
 
class Graph {
    int V;
    List > adj;
 
    Graph(int V)
    {
        this.V = V;
        adj = new ArrayList<>(V);
        for (int i = 0; i < V; i++) {
            adj.add(i, new ArrayList<>());
        }
    }
 
    // add edge to graph
    void addEdge(int s, int d)
    {
        adj.get(s).add(d);
    }
 
    // BFS function to find path
    // from source to sink
    boolean BFS(int s, int d)
    {
        // Base case
        if (s == d)
            return true;
 
        // Mark all the vertices as not visited
        boolean[] visited = new boolean[V];
 
        // Create a queue for BFS
        Queue queue
            = new LinkedList<>();
 
        // Mark the current node as visited and
        // enqueue it
        visited[s] = true;
        queue.offer(s);
 
        // it will be used to get all adjacent
        // vertices of a vertex
        List edges;
 
        while (!queue.isEmpty()) {
            // Dequeue a vertex from queue
            s = queue.poll();
 
            // Get all adjacent vertices of the
            // dequeued vertex s. If a adjacent has
            // not been visited, then mark it visited
            // and enqueue it
            edges = adj.get(s);
            for (int curr : edges) {
                // If this adjacent node is the
                // destination node, then return true
                if (curr == d)
                    return true;
 
                // Else, continue to do BFS
                if (!visited[curr]) {
                    visited[curr] = true;
                    queue.offer(curr);
                }
            }
        }
 
        // If BFS is complete without visiting d
        return false;
    }
 
    static boolean isSafe(
        int i, int j, int[][] M)
    {
        int N = M.length;
        if (
            (i < 0 || i >= N)
            || (j < 0 || j >= N)
            || M[i][j] == 0)
            return false;
        return true;
    }
 
    // Returns true if there is a
    // path from a source (a
    // cell with value 1) to a
    // destination (a cell with
    // value 2)
    static boolean findPath(int[][] M)
    {
        // Source and destination
        int s = -1, d = -1;
        int N = M.length;
        int V = N * N + 2;
        Graph g = new Graph(V);
 
        // Create graph with n*n node
        // each cell consider as node
        int k = 1; // Number of current vertex
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (M[i][j] != 0) {
 
                    // connect all 4 adjacent
                    // cell to current cell
                    if (isSafe(i, j + 1, M))
                        g.addEdge(k, k + 1);
                    if (isSafe(i, j - 1, M))
                        g.addEdge(k, k - 1);
                    if (i < N - 1
                        && isSafe(i + 1, j, M))
                        g.addEdge(k, k + N);
                    if (i > 0 && isSafe(i - 1, j, M))
                        g.addEdge(k, k - N);
                }
 
                // source index
                if (M[i][j] == 1)
                    s = k;
 
                // destination index
                if (M[i][j] == 2)
                    d = k;
                k++;
            }
        }
 
        // find path Using BFS
        return g.BFS(s, d);
    }
 
    // Driver program to check above function
    public static void main(
        String[] args) throws Exception
    {
        int[][] M = { { 0, 3, 0, 1 },
                      { 3, 0, 3, 3 },
                      { 2, 3, 3, 3 },
                      { 0, 3, 3, 3 } };
 
        System.out.println(
            ((findPath(M)) ? "Yes" : "No"));
    }
}
 
// This code is contributed by abhay379201

Python3

# Python3 program to find path between two
# cell in matrix
from collections import defaultdict
class Graph:
    def __init__(self):
        self.graph = defaultdict(list)
     
    # add edge to graph
    def addEdge(self, u, v):
        self.graph[u].append(v)
 
    # BFS function to find path from source to sink    
    def BFS(self, s, d):
         
        # Base case
        if s == d:
            return True
             
        # Mark all the vertices as not visited
        visited = [False]*(len(self.graph) + 1)
 
        # Create a queue for BFS
        queue = []
        queue.append(s)
 
        # Mark the current node as visited and
        # enqueue it
        visited[s] = True
        while(queue):
 
            # Dequeue a vertex from queue
            s = queue.pop(0)
 
            # Get all adjacent vertices of the
            # dequeued vertex s. If a adjacent has
            # not been visited, then mark it visited
            # and enqueue it
            for i in self.graph[s]:
                 
                # If this adjacent node is the destination
                # node, then return true
                if i == d:
                    return True
 
                # Else, continue to do BFS
                if visited[i] == False:
                    queue.append(i)
                    visited[i] = True
 
        # If BFS is complete without visiting d
        return False
 
def isSafe(i, j, matrix):
    if i >= 0 and i <= len(matrix) and j >= 0 and j <= len(matrix[0]):
        return True
    else:
        return False
 
# Returns true if there is a path from a source (a
# cell with value 1) to a destination (a cell with
# value 2)
def findPath(M):
    s, d = None, None # source and destination
    N = len(M)
    g = Graph()
 
    # create graph with n * n node
    # each cell consider as node
    k = 1 # Number of current vertex
    for i in range(N):
        for j in range(N):
            if (M[i][j] != 0):
 
                # connect all 4 adjacent cell to
                # current cell
                if (isSafe(i, j + 1, M)):
                    g.addEdge(k, k + 1)
                if (isSafe(i, j - 1, M)):
                    g.addEdge(k, k - 1)
                if (isSafe(i + 1, j, M)):
                    g.addEdge(k, k + N)
                if (isSafe(i - 1, j, M)):
                    g.addEdge(k, k - N)
             
            if (M[i][j] == 1):
                s = k
 
            # destination index    
            if (M[i][j] == 2):
                d = k
            k += 1
 
    # find path Using BFS
    return g.BFS(s, d)
 
# Driver code
if __name__=='__main__':
    M =[[0, 3, 0, 1], [3, 0, 3, 3], [2, 3, 3, 3], [0, 3, 3, 3]]
    if findPath(M):
        print("Yes")
    else:
        print("No")
 
# This Code is Contributed by Vikash Kumar 37

Javascript


输出
Yes

复杂性分析:

  • 时间复杂度: O(n*m)。
    矩阵的每个单元只被访问一次,因此时间复杂度为 O(n*m)。
  • 空间复杂度: O(n*m)。
    存储访问过的数组和创建队列需要空间。

简单有效的解决方案:图形本身就是矩阵。

方法:这个想法是在矩阵本身上使用广度优先搜索。

将 cell=(i,j) 视为 BFS 队列中的顶点 v。如果 u=(i+1,j) 或 u=(i-1,j) 或 u=(i,j+1) 或 u=(i,j-1) 则将新顶点 u 放入 BFS 队列.从 cell=(i,j) 开始 BFS 算法,使得 M[i][j] 为 1,如果存在可达顶点 u=(i,j) 使得 M[i][j] 为 2,则停止并返回 true 或每个单元格都被覆盖,并且没有这样的单元格并返回 false。

算法

1) 创建 BFS 队列 q

2)扫描矩阵,如果矩阵中存在一个单元格,其值为1,则将其推送到q

3) 使用 q 运行 BFS 算法,跳过无效的单元格。即:它们是墙壁(值为0)或在矩阵边界之外,并在成功访问时将它们标记为墙壁。

3.1) 如果在BFS算法过程中有一个顶点x=(i,j)使得M[i][j]是2 停止并返回true

4) BFS 算法终止且不返回 true 则没有元素 M[i][j] 为 2,则返回 false

C++

#include 
#include 
using namespace std;
#define R 4
#define C 4
 
// Structure to define a vertex u=(i,j)
typedef struct BFSElement {
    BFSElement(int i, int j)
    {
        this->i = i;
        this->j = j;
    }
    int i;
    int j;
} BFSElement;
 
bool findPath(int M[R][C])
{
    // 1) Create BFS queue q
    queue q;
 
    // 2)scan the matrix
    for (int i = 0; i < R; ++i) {
        for (int j = 0; j < C; ++j) {
           
            // if there exists a cell in the matrix such
            // that its value is 1 then push it to q
            if (M[i][j] == 1) {
                q.push(BFSElement(i, j));
                break;
            }
        }
    }
   
    // 3) run BFS algorithm with q.
    while (!q.empty()) {
        BFSElement x = q.front();
        q.pop();
        int i = x.i;
        int j = x.j;
       
        // skipping cells which are not valid.
        // if outside the matrix bounds
        if (i < 0 || i > R || j < 0 || j > C)
            continue;
       
        // if they are walls (value is 0).
        if (M[i][j] == 0)
            continue;
 
        // 3.1) if in the BFS algorithm process there was a
        // vertex x=(i,j) such that M[i][j] is 2 stop and
        // return true
        if (M[i][j] == 2)
            return true;
       
        // marking as wall upon successful visitation
        M[i][j] = 0;
 
        // pushing to queue u=(i,j+1),u=(i,j-1)
        //                 u=(i+1,j),u=(i-1,j)
        for (int k = -1; k <= 1; k += 2) {
            q.push(BFSElement(i + k, j));
            q.push(BFSElement(i, j + k));
        }
    }
   
    // BFS algorithm terminated without returning true
    // then there was no element M[i][j] which is 2, then
    // return false
    return false;
}
 
// Main Driver code
int main()
{
 
    int M[R][C] = { { 0, 3, 0, 1 },
                    { 3, 0, 3, 3 },
                    { 2, 3, 3, 3 },
                    { 0, 3, 3, 3 } };
 
    (findPath(M) == true) ? cout << "Yes"
                          : cout << "No" << endl;
 
    return 0;
}

Java

import java.io.*;
import java.util.*;
 
class BFSElement
{
    int i, j;
    BFSElement(int i, int j)
    {
        this.i = i;
        this.j = j;
    }
}
 
class GFG {
    static int R = 4, C = 4;
    BFSElement b;
     
    static boolean findPath(int M[][])
    {
       
        // 1) Create BFS queue q
        Queue q = new LinkedList<>();
       
        // 2)scan the matrix
        for (int i = 0; i < R; ++i)
        {
            for (int j = 0; j < C; ++j)
            {
                
                // if there exists a cell in the matrix such
                // that its value is 1 then push it to q
                if (M[i][j] == 1) {
                    q.add(new BFSElement(i, j));
                    break;
                }
            }
         
        }
     
        // 3) run BFS algorithm with q.
        while (q.size() != 0)
        {
            BFSElement x = q.peek();
            q.remove();
            int i = x.i;
            int j = x.j;
           
            // skipping cells which are not valid.
            // if outside the matrix bounds
            if (i < 0 || i >= R || j < 0 || j >= C)
                continue;
            
            // if they are walls (value is 0).
            if (M[i][j] == 0)
                continue;
      
            // 3.1) if in the BFS algorithm process there was a
            // vertex x=(i,j) such that M[i][j] is 2 stop and
            // return true
            if (M[i][j] == 2)
                return true;
            
            // marking as wall upon successful visitation
            M[i][j] = 0;
      
            // pushing to queue u=(i,j+1),u=(i,j-1)
            // u=(i+1,j),u=(i-1,j)
            for (int k = -1; k <= 1; k += 2)
            {
                q.add(new BFSElement(i + k, j));
                q.add(new BFSElement(i, j + k));
            }
        }
             
        // BFS algorithm terminated without returning true
        // then there was no element M[i][j] which is 2, then
        // return false
        return false;
     
    }
   
    // Main Driver code
    public static void main (String[] args)
    {
        int M[][] = { { 0, 3, 0, 1 },
                    { 3, 0, 3, 3 },
                    { 2, 3, 3, 3 },
                    { 0, 3, 3, 3 } };
         
        if(findPath(M) == true)
            System.out.println("Yes");
        else
            System.out.println("No");     
    }
}
 
// This code is contributed by avanitrachhadiya2155

C#

using System;
using System.Collections.Generic;
 
public class BFSElement
{
  public int i, j;
  public BFSElement(int i, int j)
  {
    this.i = i;
    this.j = j;
  }
}
 
public class GFG
{   
  static int R = 4, C = 4;  
  static bool findPath(int[,] M)
  {
 
    // 1) Create BFS queue q
    Queue q = new Queue();
 
    // 2)scan the matrix
    for (int i = 0; i < R; ++i)
    {
      for (int j = 0; j < C; ++j)
      {
 
        // if there exists a cell in the matrix such
        // that its value is 1 then push it to q
        if (M[i, j] == 1) {
          q.Enqueue(new BFSElement(i, j));
          break;
        }
      }
 
    }
 
    // 3) run BFS algorithm with q.
    while (q.Count != 0)
    {
      BFSElement x = q.Peek();
      q.Dequeue();
      int i = x.i;
      int j = x.j;
 
      // skipping cells which are not valid.
      // if outside the matrix bounds
      if (i < 0 || i >= R || j < 0 || j >= C)
        continue;
 
      // if they are walls (value is 0).
      if (M[i, j] == 0)
        continue;
 
      // 3.1) if in the BFS algorithm process there was a
      // vertex x=(i,j) such that M[i][j] is 2 stop and
      // return true
      if (M[i, j] == 2)
        return true;
 
      // marking as wall upon successful visitation
      M[i, j] = 0;
 
      // pushing to queue u=(i,j+1),u=(i,j-1)
      // u=(i+1,j),u=(i-1,j)
      for (int k = -1; k <= 1; k += 2)
      {
        q.Enqueue(new BFSElement(i + k, j));
        q.Enqueue(new BFSElement(i, j + k));
      }
    }
 
    // BFS algorithm terminated without returning true
    // then there was no element M[i][j] which is 2, then
    // return false
    return false;
 
  }
 
  // Main Driver code
  static public void Main (){
    int[,] M = { { 0, 3, 0, 1 },
                { 3, 0, 3, 3 },
                { 2, 3, 3, 3 },
                { 0, 3, 3, 3 } };
 
    if(findPath(M) == true)
      Console.WriteLine("Yes");
    else
      Console.WriteLine("No");  
  }
}
 
// This code is contributed by rag2127

Javascript


输出
Yes

时间复杂度:O(n*m)。

空间复杂度:O(n*m)。

改进由 Ephi F.