Skip to content

Commit 995448d

Browse files
committed
add solution: lowest-common-ancestor-of-a-binary-search-tree
1 parent f5682a2 commit 995448d

File tree

1 file changed

+65
-0
lines changed
  • lowest-common-ancestor-of-a-binary-search-tree

1 file changed

+65
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
'''
2+
# 235. Lowest Common Ancestor of a Binary Search Tree
3+
4+
## 기본적인 LCA 찾기 문제이다.
5+
- LCA는 BST에서 주어진 두 노드의 최저 공통 조상이다.
6+
- 두 노드를 descendants로 가진 노드이며, 두 노드도 포함된다.
7+
8+
### LCA와 이진 탐색 트리 BST, 일반 이진트리 BT
9+
BST는 부모의 정렬 조건이 있고, BT는 부모의 정렬 조건이 없다.
10+
BST는 이진 탐색을 진행하지만, BT는 구조적 단서가 없으므로 모든 경로를 탐색해야 한다.(Post-order DFS)
11+
따라서 BT의 시간 복잡도는 O(N)이다.
12+
13+
- BT의 LCA 찾기 문제: [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/)
14+
15+
## Approach
16+
- p, q가 현재 노드보다 작으면, 왼쪽으로 이동
17+
- p, q가 현재 노드보다 크면, 오른쪽으로 이동
18+
- p, q가 현재 노드에서 양쪽으로 분리되어 나간다면, 현재 노드가 LCA이다.
19+
20+
### 재귀와 반복문
21+
재귀는 함수 호출마다 call stack 프레임이 생긴다.(push/pop)
22+
오버헤드가 발생하여 공간 복잡도가 O(H)이다.
23+
인터프리터는 특성상 재귀 성능 호출이 비교적 좋지 않다.
24+
또한 트리가 매우 깊어서 H가 큰 경우, Stack Overflow 발생 가능성이 있다.
25+
26+
## 시간 & 공간 복잡도
27+
28+
```
29+
TC: O(H)
30+
SC: O(1)
31+
```
32+
33+
### TC is O(H):
34+
- 트리의 높이만큼 반복문을 돌리므로, O(H)이다.
35+
36+
### SC is O(1):
37+
- 추가 공간 사용 없음
38+
- 만약 재귀로 풀이한다면, 함수 호출마다 콜스택 공간이 생기므로 O(H)이다.
39+
'''
40+
class Solution:
41+
'''
42+
반복문 Top-down
43+
TC: O(H)
44+
SC: O(1)
45+
'''
46+
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
47+
while root:
48+
if p.val < root.val and q.val < root.val:
49+
root = root.left
50+
elif p.val > root.val and q.val > root.val:
51+
root = root.right
52+
else:
53+
return root
54+
'''
55+
재귀 Bottom-up
56+
TC: O(H)
57+
SC: O(H)
58+
'''
59+
def lowestCommonAncestorBottomUp(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
60+
if p.val < root.val and q.val < root.val:
61+
return self.lowestCommonAncestor(root.left, p, q)
62+
elif p.val > root.val and q.val > root.val:
63+
return self.lowestCommonAncestor(root.right, p, q)
64+
else:
65+
return root

0 commit comments

Comments
 (0)