Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬으로 행렬에서 완전히 둘러싸인 섬의 개수 구하기

0과 1로 이루어진 이진 행렬(binary matrix)이 있다고 가정해 보겠습니다. 여기서 1은 육지를, 0은 물을 나타냅니다. 섬이란 물에 둘러싸여 있는 1들의 집합을 의미하는데, 이번 문제에서 구해야 할 것은 바로 완전히 물에 둘러싸인 섬, 즉 행렬의 가장자리와 맞닿아 있지 않은 섬의 개수입니다.

예를 들어 입력이 다음과 같다면,

파이썬으로 행렬에서 완전히 둘러싸인 섬의 개수 구하기

출력은 2가 됩니다. 전체 섬은 세 개지만, 그중 두 개만 사방이 물로 완전히 둘러싸여 있기 때문입니다.

문제 해결 접근 방식: DFS(깊이 우선 탐색)

이 문제는 DFS(깊이 우선 탐색)를 활용하면 효율적으로 해결할 수 있습니다. 핵심 아이디어는 각 섬을 탐색하면서 그 섬이 행렬의 경계 밖으로 뻗어 나가는지 확인하는 것입니다.

dfs() 함수의 동작 원리

  • dfs(i, j) 함수를 정의합니다. 현재 위치의 좌표 i, j를 인자로 받습니다.
  • i 또는 j가 행렬 범위를 벗어나면 False를 반환합니다. 즉, 해당 섬은 경계와 연결되어 있어 '완전히 둘러싸인 섬'이 아닙니다.
  • matrix[i][j]가 0(물)이라면 True를 반환합니다. 물은 섬의 확장을 막으므로 아직까지는 둘러싸여 있다는 의미입니다.
  • 현재 위치를 방문 처리하기 위해 matrix[i][j]를 0으로 변경합니다.
  • 상하좌우 네 방향을 재귀적으로 탐색한 결과(a, b, c, d)를 모두 AND 연산하여 반환합니다.

메인 로직

  • R은 행렬의 행 개수, C는 열 개수로 설정합니다.
  • 정답을 저장할 변수 ans를 0으로 초기화합니다.
  • 모든 칸을 순회하면서 값이 1인 지점을 발견하면 dfs(i, j)를 호출하고, 결과가 True라면 ans를 1 증가시킵니다.
  • 순회가 끝나면 ans를 반환합니다.

구현 예제

class Solution:
    def solve(self, matrix):
        def dfs(i, j):
            if i < 0 or j < 0 or i >= R or j >= C:
                return False
            if matrix[i][j] == 0:
                return True
            matrix[i][j] = 0
            a = dfs(i + 1, j)
            b = dfs(i - 1, j)
            c = dfs(i, j + 1)
            d = dfs(i, j - 1)
            return a and b and c and d

        R, C = len(matrix), len(matrix[0])
        ans = 0
        for i in range(R):
            for j in range(C):
                if matrix[i][j] == 1:
                    if dfs(i, j):
                        ans += 1
        return ans

ob = Solution()
matrix = [
    [1, 0, 0, 0, 0],
    [0, 0, 0, 1, 0],
    [0, 1, 0, 0, 0],
    [0, 1, 0, 0, 0],
    [0, 1, 1, 1, 0],
    [0, 0, 0, 0, 0]
]
print(ob.solve(matrix))

입력

matrix = [
[1, 0, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 1, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0] ]

출력

2

정리

이 알고리즘은 행렬의 모든 칸을 한 번씩 방문하므로 시간 복잡도는 O(R×C)입니다. 방문한 육지를 0으로 바꾸어 재방문을 방지하기 때문에 별도의 visited 배열 없이도 중복 탐색을 피할 수 있다는 점이 특징입니다. 이처럼 DFS를 응용하면 섬의 개수 세기, 섬의 크기 계산 등 다양한 격자(grid) 기반 그래프 문제를 손쉽게 해결할 수 있습니다.