Учитывая двумерную матрицу bool
любого размера, какой самый эффективный способ найти, является ли любое значение true
или группы значений true
огражденными кольцом значениями false
и / илиграницы матрицы.
Чтобы сделать вещи максимально простыми, давайте предположим, что только top
, right
, bottom
и left
ячейки считаются соседями любой данной ячейки, т.е.игнорировать диагональных соседей.
Чтобы облегчить чтение следующих примеров, предположим:
const bool O = true;
const bool X = false;
Например:
bool[,] matrix1 = new bool[,]
{
{O, X, O, O, O},
{O, X, O, O, O},
{O, O, O, X, O},
{O, X, O, X, O},
{O, X, O, X, O}
};
bool[,] matrix2 = new bool[,]
{
{O, X, O, O, O},
{O, X, O, O, O},
{O, O, O, X, X},
{X, O, O, O, O},
{X, O, O, O, O}
};
В обеих этих матрицах все * 1019Значения * (true
) достижимы из любых других ячеек O
на плате, поэтому мы можем сказать, что в этих матрицах нет ограждения колец.
Напротив, это не так для следующих:
bool[,] matrix3 = new bool[,]
{
{O, O, O, O, O},
{O, O, X, O, O},
{O, X, O, X, O},
{O, O, X, O, O},
{O, O, O, O, O}
}; // cell [2,2] is ring fenced
bool[,] matrix4 = new bool[,]
{
{O, O, X, O, O},
{O, X, O, X, O},
{O, X, O, X, O},
{O, O, X, O, O},
{O, O, O, O, O}
}; // cells [1,2] and [2,2] are ring fenced
bool[,] matrix5 = new bool[,]
{
{O, O, X, O, O},
{X, X, O, X, O},
{O, O, O, O, O},
{X, X, X, O, O},
{O, O, O, O, O}
}; // cells [0,0] and [0,1] are ring fenced
bool[,] matrix6 = new bool[,]
{
{O, O, O, O, O},
{X, O, O, X, O},
{O, O, X, O, O},
{O, X, O, X, X},
{O, X, O, O, O}
}; // cells [3,2], [4,2], [4,3] and [4,4] are ring fenced
Все, что мне нужно выяснить, это если есть какое-либо ограждение кольца, как только метод обнаружит это, он может перестать смотреть и просто вернуть true
, однако, если ограждение кольца не присутствуетметод должен возвращать false
.
Вот мой алгоритм:
private bool isSafe(bool[,] matrix, int row, int col, bool[,] visited)
{
return (row >= 0) && (row < matrix.GetLength(1)) && (col >= 0) &&
(col < matrix.GetLength(0)) && (matrix[row, col] &&
!visited[row, col]);
}
private void DFS(bool[,] M, int row, int col, bool[,] visited)
{
visited[row, col] = true;
//top
if(isSafe(M, row-1, col, visited)){
DFS(M, row-1, col, visited);
}
//bottom
if (isSafe(M, row + 1, col, visited))
{
DFS(M, row + 1, col, visited);
}
//left
if (isSafe(M, row, col-1, visited))
{
DFS(M, row, col-1, visited);
}
//right
if (isSafe(M, row, col + 1, visited))
{
DFS(M, row, col + 1, visited);
}
}
public bool isRingFenced(bool[,] matrix)
{
pCounter = 0;
int colLength = matrix.GetLength(0);
int rowLength = matrix.GetLength(1);
bool[,] visited = new bool[rowLength, colLength];
int islandCount = 0;
for (int i = 0; i < colLength; i++)
{
for (int j = 0; j < rowLength; j++)
{
if (matrix[i, j] && !visited[i, j])
{
DFS(matrix, i, j, visited);
islandCount++;
if(islandCount>1){
return true;
}
}
}
}
return false;
}
Есть ли лучший подход?Как мне достичь лучшего времени сложности?