💡 주어진 이차원 배열에서 문자
1
은 땅을0
은 물을 의미한다. 모든 섬의 갯수를 구하시오.
Example 1:
Input: grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
Output: 1
Example 2:
Input: grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
Output: 3
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j]
는 '0'
또는 '1'
이다.n
* m
은 시간복잡도를 결정하는 O(N)이다.n
m
의 최대 크기는 300 300이다.1
이고 방문한적이 없다면 섬 갯수를 추가한다.public class NumbersOfIsland {
private char[][] grid;
private boolean[][] visited;
private int getRows() {
return grid.length;
}
private int getColumns() {
return grid[0].length;
}
public int solve(char[][] grid) {
this.grid = grid;
this.visited = new boolean[getRows()][getColumns()];
int result = 0;
for (int i = 0; i < getRows(); i++) {
for (int j = 0; j < getColumns(); j++) {
if (isIsland(i, j) && isNotVisited(i, j)) {
result++;
bfs(i, j);
}
}
}
return result;
}
private void bfs(int curRow, int curColumn) {
Queue<Coordinate> queue = new ArrayDeque<>();
visited[curRow][curColumn] = true;
queue.add(new Coordinate(curRow, curColumn));
while (!queue.isEmpty()) {
Coordinate coordinate = queue.poll();
queue.addAll(getNeighbors(coordinate));
}
}
private List<Coordinate> getNeighbors(Coordinate curCoordinate) {
List<Coordinate> result = new ArrayList<>();
for (Directions direction : Directions.values()) {
int newRow = curCoordinate.getRow() + direction.getDirection().getRow();
int newColumn = curCoordinate.getColumn() + direction.getDirection().getColumn();
if (validCoordinate(newRow, newColumn)) {
result.add(new Coordinate(newRow, newColumn));
visited[newRow][newColumn] = true;
}
}
return result;
}
private boolean validCoordinate(int row, int column) {
return isInBoundary(row, column) && isIsland(row, column) && isNotVisited(row, column);
}
private boolean isInBoundary(int row, int column) {
return row >= 0 && column >= 0 && row < getRows() && column < getColumns();
}
private boolean isIsland(int curRow, int curColumn) {
return grid[curRow][curColumn] == '1';
}
private boolean isNotVisited(int curRow, int curColumn) {
return !this.visited[curRow][curColumn];
}
}
public class Coordinate {
private final int row;
private final int column;
public Coordinate(int row, int column) {
this.row = row;
this.column = column;
}
public int getRow() {
return row;
}
public int getColumn() {
return column;
}
}
public enum Directions {
NORTH(new Coordinate(0, 1)),
EAST(new Coordinate(1, 0)),
SOUTH(new Coordinate(0, -1)),
WEST(new Coordinate(-1, 0));
private final Coordinate direction;
Directions(Coordinate direction) {
this.direction = direction;
}
public Coordinate getDirection() {
return direction;
}
}
class NumbersOfIslandTest {
@Test
void testNumbersOfIsland() {
//given
char[][] grid1 = {
{'1', '1', '1', '1', '0'},
{'1', '1', '0', '1', '0'},
{'1', '1', '0', '0', '0'},
{'0', '0', '0', '0', '0'}
};
char[][] grid2 = {
{'1', '1', '0', '0', '0'},
{'1', '1', '0', '0', '0'},
{'0', '0', '1', '0', '0'},
{'0', '0', '0', '1', '1'}
};
NumbersOfIsland numbersOfIsland = new NumbersOfIsland();
//when
int result1 = numbersOfIsland.solve(grid1);
int result2 = numbersOfIsland.solve(grid2);
//then
Assertions.assertEquals(1, result1);
Assertions.assertEquals(3, result2);
}
}