Оптимальный алгоритм нахождения кольцевого ограждения в многомерном массиве - PullRequest
0 голосов
/ 20 сентября 2019

Учитывая двумерную матрицу 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;
}

Есть ли лучший подход?Как мне достичь лучшего времени сложности?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...