Skip to content

Commit 22edc6a

Browse files
committed
solve: lowest-common-ancestor-of-a-binary-search-tree
1 parent eede72a commit 22edc6a

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Intuition
2+
์ด์ „์— ํ’€์–ด๋ดค๋˜ ๋ฌธ์ œ์˜€๋‹ค! ์–ด๋ ค์šด ๋ฌธ์ œ์˜€๋‹ค๋Š” ์ƒ๊ฐ์„ ๋ฒ—์–ด๋˜์ง€๊ณ  ์ตœ๋Œ€ํ•œ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ’€์–ด๋ณด๋ ค๊ณ  ํ–ˆ๋‹ค.
3+
# Approach
4+
<!-- Describe your approach to solving the problem. -->
5+
1. ๋‘ ๋…ธ๋“œ(`p`, `q`) ๋ชจ๋‘ ์–ด๋– ํ•œ ๊ฒฝ๋กœ๋ฅผ ๊ฑฐ์ณ, ํ•ด๋‹น ๋…ธ๋“œ๊นŒ์ง€ ๋„์ฐฉํ•˜๋Š”์ง€ ์กฐ์ƒ๋“ค์„ ๋ฐฐ์—ด(`routes`)์— ์ €์žฅํ•œ๋‹ค.
6+
2. ๋ฐฐ์—ด์„ ํ•˜๋‚˜์”ฉ ๋น„๊ตํ•ด๊ฐ€๋ฉฐ, ๋‘ ๋…ธ๋“œ๊ฐ€ ์—‡๊ฐˆ๋ฆฌ๋Š” ์ง€์ (`pRoutes[idx] != qRoutes[idx]`)์„ ์ฐพ๋Š”๋‹ค.
7+
3. ๊ทธ ์ง€์  ๋ฐ”๋กœ ์ด์ „ ์ง€์ (`[idx-1]`)์ด ์ตœ์†Œ ๊ณตํ†ต ์กฐ์ƒ์ด๋‹ค.
8+
# Complexity
9+
- Time complexity
10+
- ํ‰๊ท : $O(log(n))$
11+
- ์ตœ์•…: $O(n)$
12+
- ํŠธ๋ฆฌ์˜ ๋†’์ด๋งŒํผ ์ˆœํšŒ๋ฅผ ํ•˜๊ฒŒ๋œ๋‹ค. ๋…ธ๋“œ๊ฐ€ n๊ฐœ ์ด๋ฏ€๋กœ, ํŠธ๋ฆฌ์˜ ๋†’์ด๋Š” ์ตœ์„  `log(n)`, ์ตœ์•… `n`์ด ๋œ๋‹ค.
13+
14+
- Space complexity
15+
- ํ‰๊ท : $O(log(n))$
16+
- ์ตœ์•…: $O(n)$
17+
- ํŠธ๋ฆฌ์˜ ๋†’์ด๋งŒํผ ์ˆœํšŒ๋ฅผ ํ•˜๊ฒŒ๋œ๋‹ค. ๋…ธ๋“œ๊ฐ€ n๊ฐœ ์ด๋ฏ€๋กœ, ํŠธ๋ฆฌ์˜ ๋†’์ด๋Š” ์ตœ์„  `log(n)`, ์ตœ์•… `n`์ด ๋œ๋‹ค.
18+
19+
# Code
20+
```go
21+
func getRoutes(head, target *TreeNode) []*TreeNode {
22+
routes := make([]*TreeNode, 0)
23+
24+
curr := head
25+
for curr.Val != target.Val {
26+
routes = append(routes, curr)
27+
if target.Val == curr.Val {
28+
break
29+
} else if target.Val < curr.Val {
30+
curr = curr.Left
31+
} else {
32+
curr = curr.Right
33+
}
34+
}
35+
return append(routes, curr)
36+
}
37+
38+
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
39+
pRoutes := getRoutes(root, p)
40+
qRoutes := getRoutes(root, q)
41+
42+
idx := 0
43+
for idx < min(len(pRoutes), len(qRoutes)) && pRoutes[idx] == qRoutes[idx] {
44+
idx++
45+
}
46+
47+
return pRoutes[idx-1]
48+
}
49+
50+
```
51+
# Intuition & Approach
52+
(์†”๋ฃจ์…˜์˜ ํ•ด๊ฒฐ๋ฒ• ์ฐธ๊ณ )
53+
54+
๋‘ ๋…ธ๋“œ๋Š” ๊ณตํ†ต์กฐ์ƒ๊นŒ์ง€๋Š” ๋™์ผํ•œ ๋Œ€์†Œ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ฐ€, ๊ณตํ†ต ์กฐ์ƒ ์ดํ›„๋กœ ๋Œ€์†Œ๊ด€๊ณ„๊ฐ€ ๊ตฌ๋ถ„๋œ๋‹ค.
55+
๋”ฐ๋ผ์„œ, ๋ฃจํŠธ์—์„œ ๋™์ผํ•œ ๋Œ€์†Œ๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” ์กฐ์ƒ๊นŒ์ง€ ์ด๋™ํ•œ๋‹ค. (๋‹ค์‹œ ๋งํ•ด, ๋Œ€์†Œ ๊ด€๊ณ„๊ฐ€ ๊ตฌ๋ถ„๋˜๋Š” ํŠน์ • ์ง€์ ์ด ๋ฐœ์ƒํ•œ๋‹ค๋ฉด ๊ทธ ์ง€์ ์˜ ๋ถ€๋ชจ๊ฐ€ ๊ณตํ†ต ์กฐ์ƒ์ด๋‹ค.)
56+
# Complexity
57+
- Time complexity
58+
- ํ‰๊ท : $O(log(n))$
59+
- ์ตœ์•…: $O(n)$
60+
- ํŠธ๋ฆฌ์˜ ๋†’์ด๋งŒํผ ์ˆœํšŒ๋ฅผ ํ•˜๊ฒŒ๋œ๋‹ค. ๋…ธ๋“œ๊ฐ€ n๊ฐœ ์ด๋ฏ€๋กœ, ํŠธ๋ฆฌ์˜ ๋†’์ด๋Š” ์ตœ์„  `log(n)`, ์ตœ์•… `n`์ด ๋œ๋‹ค.
61+
62+
- Space complexity: $O(1)$
63+
- ๋ณ„๋„ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์˜ ์ˆœํšŒ๋งŒ์ด ์กด์žฌํ•œ๋‹ค.
64+
65+
# Code
66+
## For-loop
67+
```go
68+
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
69+
curr := root
70+
for {
71+
if p.Val < curr.Val && q.Val < curr.Val {
72+
curr = curr.Left
73+
} else if p.Val > curr.Val && q.Val > curr.Val {
74+
curr = curr.Right
75+
} else {
76+
break
77+
}
78+
}
79+
return curr
80+
}
81+
82+
```
83+
## Recursion
84+
```go
85+
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
86+
if p.Val < root.Val && q.Val < root.Val {
87+
return lowestCommonAncestor(root.Left, p, q)
88+
} else if p.Val > root.Val && q.Val > root.Val {
89+
return lowestCommonAncestor(root.Right, p, q)
90+
}
91+
return root
92+
}
93+
94+
```
95+
: ํ•จ์ˆ˜ ์ฝœ์Šคํƒ์ด ํŠธ๋ฆฌ์˜ ๋†’์ด๋งŒํผ ์ฆ๊ฐ€ํ•˜๋ฏ€๋กœ, ๊ณต๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(n)๊นŒ์ง€ ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. (์ฒ˜์Œ ํ•ด๊ฒฐ๋ฒ•์˜ ๊ณต๊ฐ„ ๋ณต์žก๋„์ฒ˜๋Ÿผ.)

0 commit comments

Comments
ย (0)