给出一个由O和X组成的字符矩阵,找出只包含'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
解释。请看下面的图片来理解
上述矩阵的图片
使用包含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)
