Количество островов
Описание задачи #
Дана матрица размером m * n, которая представляет собой карту.
Каждая ячейка матрицы может принимать следующие значения:
1— суша0— вода
Остров окружен водой и образован путем соединения соседних земель по горизонтали или вертикали. Вы можете предположить, что все четыре края сетки окружены водой.
Напишите функцию, которая принимает на вход матрицу и возвращает количество островов в ней.
Ограничения #
m == grid.lengthn == grid[i].length1 <= m, n <= 300- Допустимые значения в матрице —
0или1
Примеры #
-
Входные данные
[ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"], ]Ответ:
1 -
Входные данные
[ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"], ]Ответ:
3
Решение #
Для того чтобы посчитать количество островов в матрице достаточно определить хотя бы по одной точке из каждого острова.
Первым делом создадим счетчик для подсчета количества островов, который будет иметь начальное значение равное 0.
Далее для подсчета необходимо перебрать все элементы матрицы и выполнить следующие проверки:
- если значение элемента равно
0, то мы просто его пропускаем; - если значение равно
1, то мы засчитываем попадание в остров, прибавляем единицу к счетчику и рекурсивно удаляем остров из матрицы.
После попадания в остров нам необходимо удалять остров из массива, чтобы при проверке последующих элементов не учитывать его повторно. Таким образом каждый раз встречая единицу мы будем однозначно понимать, что нашли новый остров.
-
package number_of_islands func numIslands(grid [][]byte) int { counter := 0 for i := 0; i < len(grid); i++ { for j := 0; j < len(grid[i]); j++ { if grid[i][j] == '1' { counter++ deepScan(grid, i, j) } } } return counter } func deepScan(grid [][]byte, i, j int) { grid[i][j] = '0' if j < len(grid[i])-1 && grid[i][j+1] == '1' { deepScan(grid, i, j+1) } if i < len(grid)-1 && grid[i+1][j] == '1' { deepScan(grid, i+1, j) } if j > 0 && grid[i][j-1] == '1' { deepScan(grid, i, j-1) } if i > 0 && grid[i-1][j] == '1' { deepScan(grid, i-1, j) } } -
export const numIslands = (grid: string[][]): number => { let counter = 0 for (let i = 0; i < grid.length; i++) { for (let j = 0; j < grid[i].length; j++) { if (grid[i][j] == '1') { counter++ deepScan(grid, i, j) } } } return counter } export const deepScan = (grid: string[][], i: number, j: number): void => { grid[i][j] = '0' if (j < grid[i].length - 1 && grid[i][j + 1] == '1') { deepScan(grid, i, j + 1) } if (i < grid.length - 1 && grid[i + 1][j] == '1') { deepScan(grid, i + 1, j) } if (j > 0 && grid[i][j - 1] == '1') { deepScan(grid, i, j - 1) } if (i > 0 && grid[i - 1][j] == '1') { deepScan(grid, i - 1, j) } }
Оценка сложности #
По времени
Так как мы перебираем всю матрицу, то сложность перебора будет равна O(m * n).
Также дополнительно может вызываться очистка острова, которая в худшем случае может занять O(m * n) операций (если вся матрица занята единицами.).
Таким образом суммарная сложность O(2(m * n)), которая упрощается до O(m * n).
По памяти
O(1) — константная, так как мы выделяем дополнительную память только для хранения счетчиков.