Рубрики
Без рубрики

Решение количества островов с использованием глубинного поиска 🏝️

Сегодняшняя проблема – это довольно общий вопрос об интервью на лецкоде, называемом количеством островов …. Теги с алгоритмами, Python.

Сегодняшняя проблема – довольно общее вопрос интервью на летекоде под названием Количество островов Отказ

Учитывая 2D карту сетки «1» (земля) и 0 ‘(вода), подсчитайте количество островов. Остров окружен водой и формируется путем соединения соседних земель горизонтально или вертикально. Вы можете предположить, что все четыре края сетки все окружены водой.

Я буду честен, я не сразу же прыгнул, чтобы думать о том, чтобы использовать первый поиск по этой проблеме. Я изначально подумал о подходе грубого прихода к итерации через каждый элемент в сетке и отслеживание всех соседних элементов в какой-либо другой структуре данных. Я узнал об обоих DFS, так и в BFS в контексте графов и деревьев, поэтому оно не было мгновенно щелкнуть, чтобы алгоритм DF или BFS подойдет здесь.

Как только я приземлился на использование алгоритма DFS, мне нужно было выяснить, как сделать его применимым к этой конкретной проблеме. Я знал, что хочу начать в верхнем левом углу сетки (при координатах 0, 0) и сделать что-то Как только я столкнулся с пространством сетки, который составлял 1. Если мы столкнемся с сеткой, которое равно 1, то мы знаем, что мы ударили остров, и нам нужно будет изучить окружающие элементы сетки, чтобы увидеть, насколько велик этот остров.

Грубый, общий план атаки состоит в том, чтобы повторить через нашу сетку, и всякий раз, когда мы находим «1», переверните «1» на «0», а затем запустите DFS на всех соседних пространствах, пока мы не исчерпали всю сетку. Запуск DFS рекурсивно используя исходное пространство, которое равно 1 должно позволить нам получить «общий размер» острова, который мы могли бы использовать, чтобы фактически поддерживать рабочее количество общего количества островов.

Почти всегда, первое, что я сделаю, прежде чем погрузиться в мясо алгоритма, – подумать о возможных случаях края. Я обычно не поймаю их на этом этапе, но обычные краевые чехлы я напишу в первую очередь, если вход 0, пустой, нулевой, нет и т. Д.

def num_islands(grid: List[List[str]]) -> int:
    # variable to hold the number of islands
    island_count = 0

    # first check if there are values in the grid
    if not grid:
        return island_count

Далее я хочу установить длину и ширину сетки, чтобы убедиться, что мое решение никогда не достигнет границ. Я сделаю это, установив м и n , соответственно.

    # m will represent the number of rows in our grid
    m = len(grid)

    # n will represent the number of columns in our grid
    n = len(grid[0])

Теперь, когда у меня есть свои границы всех квадратов, пришло время двигаться на мясо раствора – написание алгоритма поиска первого глубины. Есть много отличных ресурсов онлайн с объяснениями и образцами кода DFS, начиная от GeeksForGeeks , Базеки И больше, поэтому я не буду проходить по деталям здесь.

    def dfs(i, j):
        # check if i and j are still on the grid
        # check if the current spot doesn't already equal 1
        if(i < 0 or j < 0 or i >= m or j >= n or grid[i][j] != "1"):
            return

        # otherwise
        else:
            # set current grid space to 0
            grid[i][j] = 0
            # run dfs on all surrounding elements
            dfs(i - 1, j)
            dfs(i + 1, j)
            dfs(i, j - 1)
            dfs(i, j + 1)

Я использую функцию помощника для реализации DFS, и функция примет параметры i и J которые представляют текущую координату сетки. Допустим, мы столкнулись с нашими первыми «1» на (3, 2), мы будем вызывать DFS (3, 2).

Сразу у летучей мыши мы проверяем, действительно ли позиция, и убедитесь, что текущее место еще не равно 1. Если какие-либо из этих случаев верно, мы можем вернуть в начале. Затем нам нужно проверить, было ли пространство сетки 0 (что означает, что это водное пространство), мы также можем выйти из функции.

В противном случае текущее пространство сетки должно быть равно «1», поэтому мы перевернем это на «0» и рекурсивно позвонить нашему DFS Функция помощника на всех соседних элементах (вверх, вниз, слева, справа).

Честно говоря, на данный момент большая часть тяжелой работы окончена! 🎉 Нам просто нужно написать код, чтобы повторить сетку и идентифицировать эти 1-х!

    # initial for loop to iterate through the grid
        for i in range(m):
            # iterating through each row
            for j in range(n):
                # if current grid space is 1
                if(grid[i][j] == "1"):
                    # increment island count
                    island_count += 1
                    # run dfs using the current spot as the root
                    dfs(i, j)
                # if grid space is 0
                else:
                    # continue searching
                    continue

        # return count when done          
        return island_count

Вот это, в финальной форме!

    def num_islands(grid: List[List[str]]) -> int:
        # variable to hold the number of islands
        island_count = 0

        # first check if there are values in the grid
        if not grid:
            return island_count

        # set the lengths:
        # m represents the number of rows
        m = len(grid)
        # n represents the number of columns
        n = len(grid[0])

        # definition of depth-first search
        def dfs(i, j):
            # check if i and j are still on the grid
            # check if the current grid spot doesn't already equal 1
            if(i < 0 or j < 0 or i >= m or j >= n or grid[i][j] != "1"):
                return

            # otherwise
            else:
                # set current grid space to 0
                grid[i][j] = 0
                # run dfs on all surrounding elements
                dfs(i - 1, j)
                dfs(i + 1, j)
                dfs(i, j - 1)
                dfs(i, j + 1)

        # initial for loop to iterate through the grid
        for i in range(m):
            # iterating through each row
            for j in range(n):
                # if current grid space is 1
                if(grid[i][j] == "1"):
                    # increment island count
                    island_count += 1
                    # run dfs using the current spot as the root
                    dfs(i, j)
                # if grid space is 0
                else:
                    # continue searching
                    continue

        # return count when done          
        return island_count

Сложность времени для этой реализации является O (Mn), где м это количество строк в нашей сетке и n это количество столбцов.

Оригинал: “https://dev.to/stuttskl/solving-number-of-islands-using-a-depth-first-search-6f3”