들어가며
안녕하세요! 이번 포스팅에서는 깊이 우선 탐색(DFS, Depth-First Search) 알고리즘에 대해 알아보겠습니다. DFS는 그래프나 트리 구조에서 사용되는 탐색 알고리즘으로, 최대한 깊이 들어간 후 인접 노드를 탐색하는 방법입니다. 코딩테스트에 자주 출제되는 중요한 주제이니 알고리즘 이해와 문제 풀이 능력을 기르기 위해 꼭 마스터해두길 추천합니다.
문제 설명
문제 제목: 섬의 개수
주어진 2D 배열에서 ‘1’은 육지, ‘0’은 바다를 나타냅니다. 연속적으로 연결된 ‘1’들은 하나의 섬으로 간주합니다. 육지 ‘1’과 수평 또는 수직으로 연결된 모든 ‘1’은 같은 섬에 포함됩니다. 주어진 배열에서 섬의 개수를 구하세요.
입력 예시
[
[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[1, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[1, 0, 1, 0, 1]
]
출력 예시
섬의 개수: 5
문제 풀이 과정
이 문제는 DFS 알고리즘을 사용하여 해결할 수 있습니다. 다음 단계를 통해 문제를 해결해보겠습니다.
1단계: 그래프 표현
문제에서는 2D 배열로 주어지는 그래프를 다루고 있습니다. 각 ‘1’은 육지를 나타내며, 문제를 해결하기 위해서는 이 육지들이 어떻게 연결되어 있는지를 파악해야 합니다.
2단계: DFS 알고리즘 구현
DFS를 사용하여 각 육지 ‘1’을 방문할 때, 그것이 속한 섬을 하나로 묶어야 합니다. 이를 위해 재귀 함수를 정의하여 인접한 육지 ‘1’들을 방문하게 만듭니다.
3단계: 코드 작성
이제 기본적인 DFS 알고리즘을 구현하는 코드를 작성해보겠습니다. 코틀린을 사용하여 다음과 같은 방식으로 구현할 수 있습니다.
fun numIslands(grid: Array): Int {
if (grid.isEmpty()) return 0
var count = 0
fun dfs(i: Int, j: Int) {
if (i < 0 || i >= grid.size || j < 0 || j >= grid[0].size || grid[i][j] == '0') {
return
}
grid[i][j] = '0' // 방문 처리
dfs(i - 1, j) // 상
dfs(i + 1, j) // 하
dfs(i, j - 1) // 좌
dfs(i, j + 1) // 우
}
for (i in grid.indices) {
for (j in grid[i].indices) {
if (grid[i][j] == '1') {
count++
dfs(i, j) // 새로운 섬 발견
}
}
}
return count
}
4단계: 코드 설명
위의 코드에서 numIslands
함수는 2D 배열을 매개변수로 받고, 섬의 개수를 반환합니다.
내부의 dfs
함수는 재귀적으로 각 육지를 방문하며, 이미 방문한 육지는 ‘0’으로 변경하여 중복 방문을 방지합니다.
이중 루프를 통해 배열의 각 요소를 확인하며, ‘1’이 발견될 때마다 섬의 개수를 증가시키고 dfs
를 호출합니다.
5단계: 시간 복잡도 및 공간 복잡도
DFS 알고리즘의 시간 복잡도는 O(M * N)입니다. M은 행의 개수, N은 열의 개수를 의미합니다.
공간 복잡도는 O(H)이며, H는 재귀 호출 스택의 깊이를 의미합니다. 최악의 경우에는 O(M + N)이 될 수 있습니다.
테스트 케이스 분석
위 설명으로 기본적인 코드를 작성해보았는데, 다양한 테스트 케이스를 통해 코드의 정확성을 검증하는 것이 중요합니다.
다음은 몇 가지 테스트 케이스에 대한 설명입니다.
-
테스트 케이스 1:
입력:[[1,1,0,0],[0,1,0,0],[0,0,0,1],[1,0,0,1]]
예상 출력: 2
-
테스트 케이스 2:
입력:[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
예상 출력: 0
-
테스트 케이스 3:
입력:[[1,1,1,1],[1,0,0,0],[1,1,1,1]]
예상 출력: 1
마치며
이번 포스팅에서는 깊이 우선 탐색(DFS)에 대해 설명하고, 예제 문제를 통해 알고리즘을 직접 구현해보았s습니다.
DFS는 그래프 문제를 해결할 때 매우 유용한 도구이므로, 코딩테스트에서 자주 접할 수 있습니다.
다양한 문제를 풀어보면서 DFS를 깊이 있게 이해하고 활용할 수 있도록 연습해보세요.