java|计算给定矩阵中只有'X'的子矩阵的数量

99 阅读3分钟

给出一个由OX组成的字符矩阵,找出只包含'X'并且四面都被'O'包围的子矩阵的数量。

例子。

输入:grid[][] = {{X, O, X}, {O, X, O}, {X, X, X}}
输出:3

输入:grid[][] = { {'X', 'O', 'X', 'X' }, { 'O', 'O', 'X', 'X' }, { 'X', 'X', 'O', 'O' }, { 'O', 'O', 'X' }, { 'X' , 'O' , 'O' }};
输出:5
解释。请看下面的图片来理解

Image of the above matrix

上述矩阵的图片

使用包含X的子矩阵 DFS:

按照下面的思路来解决这个问题。

对每一个X运行DFS,并找到它所在的子矩阵。

以下是解决该问题的步骤。

  • 初始化一个二维数组(例如visited[][]),其大小与给定的矩阵相同,用于跟踪给定矩阵中的被访单元。
  • 在给定的矩阵中,在未访问的单元格上执行DFS遍历,其值为'X'。
    • 然后将该单元格标记为已访问,并递归调用DFS的所有四个方向,即右、左、上、下,使所有连接的 "X "成为已访问,并在结果计数中计算连接的 "X "形状。
  • 重复上述步骤,直到所有具有 "X "值的单元格都没有被访问。

下面是上述方法的实现。

java

// Java Code to implement above approach
import java.util.*;
 
public class Solution {
 
  // Function to check if it is valid
  // to move on the next cell
  static boolean isValid(int row, int col, char[][] grid,
                         int[][] visited)
  {
    return (row < grid.length) && (row >= 0)
      && (col < grid[0].length) && (col >= 0)
      && (grid[row][col] == 'X')
      && (visited[row][col] == 0);
  }
 
  // Function to implement dfs
  static void dfs(int row, int col, char[][] grid,
                  int[][] visited)
  {
    if (!isValid(row, col, grid, visited))
      return;
    visited[row][col] = 1;
    dfs(row + 1, col, grid, visited);
    dfs(row, col + 1, grid, visited);
    dfs(row - 1, col, grid, visited);
    dfs(row, col - 1, grid, visited);
  }
 
  // Function to count the total number of submatrices
  static int xShape(char[][] grid)
  {
    int n = grid.length;
    int m = grid[0].length;
    int[][] visited = new int[n][m];
    int count = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        if (visited[i][j] == 0
            && grid[i][j] == 'X') {
          dfs(i, j, grid, visited);
          count++;
        }
      }
    }
    return count;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    char[][] grid = { { 'X', 'O', 'X', 'X' },
                     { 'O', 'O', 'X', 'X' },
                     { 'X', 'X', 'O', 'O' },
                     { 'O', 'O', 'X', 'X' },
                     { 'X', 'O', 'O', 'O' } };
    System.out.println(xShape(grid));
  }
}
 
// This code is contributed by karandeep1234

输出

5

时间复杂度。 O(ROW x COL)
辅助空间。 O(ROW x COL),其中ROW= 给定网格中的行数,COL= 给定网格中的列数。

空间优化的方法来寻找包含X的子矩阵。

在上述方法中,我们使用了一个额外的空间,即visited[ ][ ]数组,以保持对所访问单元的跟踪。另外,我们也可以不使用辅助空间,但为此,我们必须改变给定的矩阵。

以下是解决这个问题的步骤。

  • 在给定矩阵中具有 "X "值的单元格上执行DFS遍历,然后将该单元格的值改为 "O",这样它就不会再访问该单元格,并且
  • 在所有四个方向,即右、左、上和下,递归地调用DFS,将所有连接的 "X "改为 "O",并在结果计数中计算连接的 "X "形状。
  • 重复上述步骤,直到给定矩阵中的所有 "X "都没有变成 "O"。

下面是上述方法的实现。

java

/*package whatever //do not write package name here */
import java.io.*;
 
class GFG {
 
  // Function to check if it is valid
  // to traverse the next cell
  static boolean isValid(int row, int col, char[][] grid)
  {
    return (row < grid.length) && (row >= 0)
      && (col < grid[0].length) && (col >= 0)
      && (grid[row][col] == 'X');
  }
 
  // Function to implement dfs
  static void dfs(int row, int col, char[][] grid)
  {
    if (!isValid(row, col, grid))
      return;
    grid[row][col] = 'O';
    dfs(row + 1, col, grid);
    dfs(row, col + 1, grid);
    dfs(row - 1, col, grid);
    dfs(row, col - 1, grid);
  }
 
  // Function to count the submatrices
  static int xShape(char[][] grid)
  {
    // Code here
    int n = grid.length;
    int m = grid[0].length;
    int count = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        if (grid[i][j] == 'X') {
          dfs(i, j, grid);
          count++;
        }
      }
    }
    return count;
  }
 
  public static void main(String[] args)
  {
    char[][] grid = { { 'X', 'O', 'X', 'X' },
                     { 'O', 'O', 'X', 'X' },
                     { 'X', 'X', 'O', 'O' },
                     { 'O', 'O', 'X', 'X' },
                     { 'X', 'O', 'O', 'O' } };
 
    // Function Call
    System.out.println(xShape(grid));
  }
}
 
// This code is contributed by aadityaburujwale.

输出

5

时间复杂度。O(ROW x COL)
辅助空间。O(1)