Сегодняшняя проблема – довольно общее вопрос интервью на летекоде под названием Количество островов Отказ
Учитывая 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”