99클럽 코테 스터디 6일차 TIL - 섬의 개수 (DFS/BFS)

Hyejin·2025년 4월 7일
0

99Club

목록 보기
7/21
post-thumbnail

문제: https://www.acmicpc.net/problem/4963
알고리즘 분류: 그래프 이론, 그래프 탐색, 너비 우선 탐색(BFS), 깊이 우선 탐색(DFS)

문제 파악

  • 그래프 이론에서 주로 다루는 "연결 요소(Connected Components)"를 찾는 문제

  • 섬의 개수는 연결된 땅(1)의 그룹 수를 세는 것과 같다

  • 지도는 0(바다)과 1(땅)로 구성된 2차원 배열

  • 가로, 세로, 대각선으로 연결된 1(땅)은 하나의 섬으로 간주

접근 방법 - DFS(깊이우선탐색)

  1. 지도의 모든 칸을 순회

  2. 0 땅(1)을 발견하면 해당 위치에서 DFS함수를 시작해 연결된 모든 땅을 방문하고 표시

  3. 한 번의 DFS함수가 완료되면 하나의 섬을 발견한 것이므로 섬 카운터 증가시킴

  4. 모든 칸을 순회할 때까지 1-3번 반복

내 코드

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

let lineIndex = 0;
const results = [];

while (lineIndex < input.length) {
    
  const [w, h] = input[lineIndex++].split(' ').map(Number);
  
  if (w === 0 && h === 0) break;
  
  const map = [];
  for (let i = 0; i < h; i++) {
    map.push(input[lineIndex++].split(' ').map(Number));
  }
  
  const visited = Array(h).fill().map(() => Array(w).fill(false));
  
  let islandCount = 0;
  
  for (let i = 0; i < h; i++) {
    for (let j = 0; j < w; j++) {
      if (map[i][j] === 1 && !visited[i][j]) {
        dfs(map, visited, i, j, h, w);
        islandCount++;
      }
    }
  }
  
  results.push(islandCount);
}

function dfs(map, visited, i, j, h, w) {

  if (i < 0 || i >= h || j < 0 || j >= w) return;
  
  if (visited[i][j] || map[i][j] === 0) return;
  
  visited[i][j] = true;
  
  const directions = [
    [-1, -1], [-1, 0], [-1, 1],
    [0, -1],           [0, 1],
    [1, -1],  [1, 0],  [1, 1]
  ];
  
  for (const [dx, dy] of directions) {
    dfs(map, visited, i + dx, j + dy, h, w);
  }
}

console.log(results.join('\n'));

성능

  • 시간복잡도(실행속도): 172 ms

  • 공간복잡도(메모리): 12464 KB

개선할 점

  • 재귀 호출을 사용하는 DFS는, 지도 크기가 클 경우 스택 오버플로우 발생 가능성 ⬆️

  • BFS를 사용하면 이런 문제를 피할 수 있고, 특히 자바스크립트에서는 더 효율적일 수 있음

참고
https://bedecked-operation-4d1.notion.site/99-6-TIL-1ceeb405261e809699ffcb380cbc3e32

0개의 댓글