Skip to content

Commit de68c2e

Browse files
committed
solve(w09): 417. Pacific Atlantic Water Flow
1 parent 0483b52 commit de68c2e

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# https://leetcode.com/problems/pacific-atlantic-water-flow/
2+
3+
from typing import List
4+
5+
class Solution:
6+
def pacificAtlantic_bfs(self, heights: List[List[int]]) -> List[List[int]]:
7+
"""
8+
[Complexity]
9+
- TC: O(m * n) (모든 칸은 최대 한 번씩 방문)
10+
- SC: O(m * n) (queue)
11+
12+
[Approach]
13+
거꾸로 각 바다에 맞닿아있는 edges에서부터 시작해서, BFS로 height 값이 gte인 칸(-> 바다에서부터 거꾸로 확인하므로)을 방문하며 기록한다.
14+
pacific & atlantic 쪽 edges에서 시작해서 방문한 칸들의 교집합을 구하면 된다.
15+
"""
16+
from collections import deque
17+
18+
m, n = len(heights), len(heights[0])
19+
dr, dc = [-1, 1, 0, 0], [0, 0, -1, 1]
20+
21+
def bfs(start_cells):
22+
q = deque(start_cells)
23+
visited = set(start_cells)
24+
25+
while q:
26+
r, c = q.popleft()
27+
28+
for i in range(4):
29+
nr, nc = r + dr[i], c + dc[i]
30+
31+
if (
32+
0 <= nr < m and 0 <= nc < n # valid한 범위 확인
33+
and (nr, nc) not in visited # 방문 여부 확인
34+
and heights[nr][nc] >= heights[r][c] # height 값이 현재 칸보다 gte인지 확인 (** 거꾸로 확인하므로)
35+
):
36+
q.append((nr, nc))
37+
visited.add((nr, nc))
38+
39+
return visited
40+
41+
# pacific & atlantic 쪽 edges 모으기
42+
edges_p, edges_a = [], []
43+
for r in range(m):
44+
edges_p.append((r, 0))
45+
edges_a.append((r, n - 1))
46+
for c in range(n):
47+
edges_p.append((0, c))
48+
edges_a.append((m - 1, c))
49+
50+
# edges로부터 BFS로 방문
51+
visited_p = bfs(edges_p)
52+
visited_a = bfs(edges_a)
53+
54+
# pacific과 atlantic의 교집합 반환
55+
return [list(cell) for cell in visited_p & visited_a]
56+
57+
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
58+
"""
59+
[Complexity]
60+
- TC: O(m * n) (모든 칸은 최대 한 번씩 방문)
61+
- SC: O(m * n) (call stack)
62+
63+
[Approach]
64+
BFS 풀이를 DFS로도 접근 가능하다.
65+
"""
66+
m, n = len(heights), len(heights[0])
67+
dr, dc = [-1, 1, 0, 0], [0, 0, -1, 1]
68+
visited_p, visited_a = set(), set()
69+
70+
def dfs(r, c, visited):
71+
# base condition
72+
if (r, c) in visited: # 방문 여부 확인
73+
return
74+
75+
# 방문 처리
76+
visited.add((r, c))
77+
78+
# recur
79+
for i in range(4):
80+
nr, nc = r + dr[i], c + dc[i]
81+
82+
if (
83+
0 <= nr < m and 0 <= nc < n # valid한 범위 확인
84+
and heights[nr][nc] >= heights[r][c] # height 값이 현재 칸보다 gte인지 확인 (** 거꾸로 확인하므로)
85+
):
86+
dfs(nr, nc, visited)
87+
88+
# edges로부터 DFS로 방문
89+
for r in range(m):
90+
dfs(r, 0, visited_p)
91+
dfs(r, n - 1, visited_a)
92+
for c in range(n):
93+
dfs(0, c, visited_p)
94+
dfs(m - 1, c, visited_a)
95+
96+
# pacific과 atlantic의 교집합 반환
97+
return [list(cell) for cell in visited_p & visited_a]

0 commit comments

Comments
 (0)