|
| 1 | +""" |
| 2 | +📚 417. Pacific Atlantic Water Flow |
| 3 | +
|
| 4 | +📌 문제 요약 |
| 5 | +- m x n 섬이 있고, 각 칸에 높이가 있음 |
| 6 | +- 왼쪽/위 = 태평양(Pacific), 오른쪽/아래 = 대서양(Atlantic) |
| 7 | +- 물은 높은 곳 → 낮거나 같은 곳으로만 흐름 |
| 8 | +- 두 바다 모두에 물이 도달할 수 있는 좌표 찾기! |
| 9 | +
|
| 10 | +📝 문제 예시 |
| 11 | +heights = [ |
| 12 | + [1, 2, 2, 3, 5], ← 태평양 (위) |
| 13 | + [3, 2, 3, 4, 4], |
| 14 | + [2, 4, 5, 3, 1], |
| 15 | + [6, 7, 1, 4, 5], |
| 16 | + [5, 1, 1, 2, 4] → 대서양 (아래) |
| 17 | +] |
| 18 | +↑ 태평양 (왼쪽) ↓ 대서양 (오른쪽) |
| 19 | +
|
| 20 | +결과: [[0,4], [1,3], [1,4], [2,2], [3,0], [3,1], [4,0]] |
| 21 | +
|
| 22 | +🎯 핵심 알고리즘 |
| 23 | +- 패턴: BFS/DFS (역방향 탐색) |
| 24 | +- 시간복잡도: O(m × n) |
| 25 | +- 공간복잡도: O(m × n) |
| 26 | +
|
| 27 | +💡 핵심 아이디어 |
| 28 | +1. 정방향(높→낮)으로 탐색하면 모든 점에서 시작해야 함 (비효율) |
| 29 | +2. 역방향(바다→섬)으로! 바다에서 시작해서 올라갈 수 있는 곳 탐색 |
| 30 | +3. 태평양에서 갈 수 있는 곳 + 대서양에서 갈 수 있는 곳 = 정답! |
| 31 | +""" |
| 32 | + |
| 33 | +from typing import List |
| 34 | +from collections import deque |
| 35 | + |
| 36 | + |
| 37 | +class Solution: |
| 38 | + def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]: |
| 39 | + if not heights: |
| 40 | + return [] |
| 41 | + |
| 42 | + m, n = len(heights), len(heights[0]) |
| 43 | + |
| 44 | + # 각 바다에서 도달 가능한 좌표 저장 |
| 45 | + pacific = set() |
| 46 | + atlantic = set() |
| 47 | + |
| 48 | + def bfs(starts, reachable): |
| 49 | + queue = deque(starts) |
| 50 | + reachable.update(starts) |
| 51 | + |
| 52 | + while queue: |
| 53 | + r, c = queue.popleft() |
| 54 | + |
| 55 | + # 상하좌우 탐색 |
| 56 | + for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]: |
| 57 | + nr, nc = r + dr, c + dc |
| 58 | + |
| 59 | + # 범위 내 & 아직 안 감 & 올라갈 수 있음 (역방향!) |
| 60 | + if (0 <= nr < m and 0 <= nc < n |
| 61 | + and (nr, nc) not in reachable |
| 62 | + and heights[nr][nc] >= heights[r][c]): |
| 63 | + queue.append((nr, nc)) |
| 64 | + reachable.add((nr, nc)) |
| 65 | + |
| 66 | + # 태평양: 왼쪽 + 위쪽 가장자리에서 시작 |
| 67 | + pacific_starts = [(i, 0) for i in range(m)] + [(0, j) for j in range(n)] |
| 68 | + bfs(pacific_starts, pacific) |
| 69 | + |
| 70 | + # 대서양: 오른쪽 + 아래쪽 가장자리에서 시작 |
| 71 | + atlantic_starts = [(i, n-1) for i in range(m)] + [(m-1, j) for j in range(n)] |
| 72 | + bfs(atlantic_starts, atlantic) |
| 73 | + |
| 74 | + # 교집합 = 두 바다 모두 도달 가능! |
| 75 | + return list(pacific & atlantic) |
| 76 | + |
0 commit comments