- ๋ชฉํ -
[์ฝ๋ ํ๊ตฌ๋ง ํ] 2021.01.05(ํ) - 3์ฃผ์ฐจ ๊ฐ์ธ ๋ชฉํ
๋ชฉํ : LCA(Lowest Common Ancestor) ์๊ณ ๋ฆฌ์ฆ ๊ฐ๋  ๋ฐ ์ค์ต ๋ฌธ์ ๋ฅผ ๋ณต์ตํ๊ณ ๋ฐฑ์ค ๋ฌธ์ ๋ฅผ ํตํด ์ค์  ๋ฌธ์ ์ ์ ์ฉํด๋ณธ๋ค. ์ค์ต์ ์ด 4๋ฌธ์ ๋ก ์๊ณ ๋ฆฌ์ฆ ์์ ์๊ฐ์ด ์งํ๋์๋ ์ค์ต ๋ฌธ์ ์ด๋ค. 1. root ์ฐพ๊ธฐ
codekodo.tistory.com
LCA(Lowest Common Ancestor) ์๊ณ ๋ฆฌ์ฆ ๊ฐ๋  ๋ฐ ์ค์ต ๋ฌธ์ ๋ฅผ ๋ณต์ตํ๊ณ ๋ฐฑ์ค ๋ฌธ์ ๋ฅผ ํตํด ์ค์  ๋ฌธ์ ์ ์ ์ฉํด๋ด์ผ๋ก์จ ์๊ณ ๋ฆฌ์ฆ ๋์๋ฐฉ์์ ๋ํด ์๊ฒ ๋์๋ค. ์ค์ต์์ ๋ฐฐ์ด ๋ฐฉ์์ผ๋ก ๋ฐฑ์ค ๋ฌธ์ ๋ฅผ ์ ๊ทผํ์์ง๋ง ์์ง ํ์ง ๋ชปํ์๋ค. ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก LCA๋ฅผ ์ ๊ทผํด๋ณด๋ ค๊ณ ํ๋ค.
1. root ์ฐพ๊ธฐ
def main():
    n = int(input())
    parent = []
    child = []
    
    for _ in range(n):
        node = list(input().split())
        if node[1] != '.' or node[2] != '.':
            parent.append(node[0])
            child.append(node[1])
            child.append(node[2])
    
    for i in parent:    # ๋ถ๋ชจ ๋
ธ๋๊ฐ ์ ์ฅ๋ ๋ฆฌ์คํธ์ ์์๊ฐ
        if i not in child:  # ์์ ๋
ธ๋๊ฐ ์ ์ฅ๋ ๋ฆฌ์คํธ์ ์์ผ๋ฉด
            root = i
            break
    
    print(root)
if __name__ == "__main__":
    main()
A B C ์ธ ๊ฒฝ์ฐ A๊ฐ ๋ถ๋ชจ ๋ ธ๋, B์ C๊ฐ ์์ ๋ ธ๋์ด๋ค.
B D . ์ธ ๊ฒฝ์ฐ B๊ฐ ๋ถ๋ชจ ๋ ธ๋, D๊ฐ ์์ ๋ ธ๋์ด๋ค.
๋ฐ๋ผ์ . ๋ฅผ 1๊ฐ ์ดํ๋ก ๊ฐ์ง๊ณ ์๋ค๋ฉด ๋ถ๋ชจ ๋ ธ๋ - ์์ ๋ ธ๋ ์์ผ๋ก ๋ณผ ์ ์๋ค.
์ดํ ๋ถ๋ชจ ๋ ธ๋์ ์์ ๋ ธ๋๋ฅผ ๊ฐ๊ฐ ๋ค๋ฅธ ๋ฆฌ์คํธ์ ์ ์ฅํ๋ค.
๋ถ๋ชจ ๋ ธ๋ ๋ฆฌ์คํธ์ ์์๊ฐ ์์ ๋ ธ๋ ๋ฆฌ์คํธ์ ์์ผ๋ฉด ์ด๋ ๋ฃจํธ ๋ ธ๋๋ผ๊ณ ๋ณผ ์ ์๋ค.
2. ํธ๋ฆฌ ์ํ
def preorder(node, tree, visit):
    visit.append(node)
    if tree[node][0] != '.':
        preorder(tree[node][0], tree, visit)
    if tree[node][1] != '.':
        preorder(tree[node][1], tree, visit)
    
    return visit
def inorder(node, tree, visit):
    if tree[node][0] != '.':
        inorder(tree[node][0], tree, visit)
    visit.append(node)
    if tree[node][1] != '.':
        inorder(tree[node][1], tree, visit)
    return visit
def postorder(node, tree, visit):
    if tree[node][0] != '.':
        postorder(tree[node][0], tree, visit)
    if tree[node][1] != '.':
        postorder(tree[node][1], tree, visit)
    visit.append(node)
    return visit
def main():
    n = int(input())
    tree = {}
    parent = []
    child = []
    
    for _ in range(n):
        node = list(input().split())
        tree[node[0]] = [node[1], node[2]]  # tree๋ฅผ ๊ตฌํํ๋ค
        if node[1] != '.' or node[2] != '.':
            parent.append(node[0])
            child.append(node[1])
            child.append(node[2])
    
    for i in parent:    # ๋ถ๋ชจ ๋
ธ๋๊ฐ ์ ์ฅ๋ ๋ฆฌ์คํธ์ ์์๊ฐ
        if i not in child:  # ์์ ๋
ธ๋๊ฐ ์ ์ฅ๋ ๋ฆฌ์คํธ์ ์์ผ๋ฉด
            root = i
            break
    
    visit = []
    print(*preorder(root, tree, visit))
    visit = []
    print(*inorder(root, tree, visit))
    visit = []
    print(*postorder(root, tree, visit))
if __name__ == "__main__":
    main()
1๋ฒ ๋ฌธ์ ๋ฅผ ํ๋ฉด์ ์ฌ์ฉํ root ๋ ธ๋ ์ฐพ๋ ์ฝ๋๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค.
์ดํ ์ ์, ์ค์, ํ์ ํ์์ ์งํํ๋ค.
์ ์ ํ์์ ๊ฒฝ์ฐ root > left > right ์์ผ๋ก ๋ฐฉ๋ฌธํ๋ค.
์ค์ ํ์์ ๊ฒฝ์ฐ left > root > right ์์ผ๋ก ๋ฐฉ๋ฌธํ๋ค.
ํ์ ํ์์ ๊ฒฝ์ฐ reft > right > root ์์ผ๋ก ๋ฐฉ๋ฌธํ๋ค.
์์ ๊ฐ๋ ์ ์ฝ๋๋ก ๊ตฌํํ๋ค.
3. ์ต์ ๊ณตํต ์กฐ์ ๋ ธ๋
def preorder(root, tree, visit, depth_list, depth): # ์ ์ํ์์ ์งํํ๋ฉด์ ๋ฐฉ๋ฌธ ์์์ ํ์ ๊น์ด๋ฅผ ์ ์ฅํ๋ค
    visit.append(root)
    depth_list.append(depth)
    depth += 1
    if tree[root][0] != '.':
        preorder(tree[root][0], tree, visit, depth_list, depth)
        visit.append(root)
        depth -= 1
        depth_list.append(depth)
    depth += 1
    if tree[root][1] != '.':
        preorder(tree[root][1], tree, visit, depth_list, depth)
        visit.append(root)
        depth -= 1
        depth_list.append(depth)
    return visit, depth_list
def main():
    n = int(input())
    tree = {}
    parent = []
    child = []
    
    for _ in range(n):
        node = list(input().split())
        tree[node[0]] = [node[1], node[2]]  # tree๋ฅผ ๊ตฌํํ๋ค
        if node[1] != '.' or node[2] != '.':
            parent.append(node[0])
            child.append(node[1])
            child.append(node[2])
    
    for i in parent:    # ๋ถ๋ชจ ๋
ธ๋๊ฐ ์ ์ฅ๋ ๋ฆฌ์คํธ์ ์์๊ฐ
        if i not in child:  # ์์ ๋
ธ๋๊ฐ ์ ์ฅ๋ ๋ฆฌ์คํธ์ ์์ผ๋ฉด
            root = i
            break
    visit = []
    depth_list = []
    depth = 0
    visit, depth_list = preorder(root, tree, visit, depth_list, depth)
    
    find = list(input().split())    # ์ง์ ๋
ธ๋
    first_index = visit.index(find[0])  # ๋ฐฉ๋ฌธ ์์๊ฐ ์ ์ฅ๋ ๋ฆฌ์คํธ์์ ์ง์ ๋
ธ๋๋ฅผ ์ฒ์ ๋ฐฉ๋ฌธํ index๋ฅผ ์ฐพ๋๋ค
    second_index = visit.index(find[1])
    if first_index > second_index:  # ํ์์ ์ํด ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํด์ค๋ค
        first_index, second_index = second_index, first_index
    max_depth = depth_list[first_index]
    for i in range(first_index+1, second_index+1): # ์ฃผ์ด์ง ๊ตฌ๊ฐ ์์์ ์ต๋ ๊น์ด๋ฅผ ์ฐพ๋๋ค
        if depth_list[i] < max_depth:
            max_depth = depth_list[i]
    
    max_index = depth_list.index(max_depth) # ์ต๋ ๊น์ด์ index๋ฅผ ์ ์ฅํ๋ค
    print(visit[max_index])
if __name__ == "__main__":
    main()
1, 2๋ฒ์ ๋ชจ๋ ํ์ฉํ ๋ฌธ์ ์ด๋ค.
์ ์ํ์์ ํตํ ๋ ธ๋ ๋ฐฉ๋ฌธ ์์์ ๋ ธ๋์ ๊น์ด๋ฅผ ๊ฐ๊ฐ ๋ค๋ฅธ ๋ฆฌ์คํธ์ ์ ์ฅํ๋ค.
์ฃผ์ด์ง ์ ๋ ฅ ๊ฐ์ผ๋ก ์ด๋ฅผ ๊ตฌํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
๋ฐฉ๋ฌธ ์์ : 1 2 4 2 5 2 1 3 1
๊น์ด : 0 1 2 1 2 1 0 1 0
์ดํ ์ ๋ ฅ๋ ์ง์ ๋ ธ๋์ ๋ฐฉ๋ฌธ ์์ ๋ฆฌ์คํธ์์์ index ๊ฐ์ ์ฐพ์๋ธ๋ค.
์ฃผ์ด์ง ์ ๋ ฅ๊ฐ(3, 4)์ผ๋ก ์ด๋ฅผ ๊ตฌํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
๋ฐฉ๋ฌธ ์์ : 1 2 4 2 5 2 1 3 1
์ด index ๊ฐ์ ๊น์ด ๋ฆฌ์คํธ์์์ ํ์ ๋ฒ์๋ก ์ ํ๊ณ ๋ฒ์ ์ด๋ด์์ ๊ฐ์ฅ ์์ ๊น์ด๊ฐ LCA์ ๊น์ด๊ฐ ๋๋ค.
๊น์ด : 0 1 2 1 2 1 0 1 0
index : 0 1 2 3 4 5 6 7 8
๋ฐ๋ผ์ LCA๋ ๋ฐฉ๋ฌธ ์์ ๋ฆฌ์คํธ์ 7๋ฒ์งธ ์์์ธ 1์ด ๋๋ค.
- ๊นํ๋ธ -
github.com/k906506/2020_Winter_Assemble-And-selfcode
k906506/2020_Winter_Assemble-And-selfcode
Contribute to k906506/2020_Winter_Assemble-And-selfcode development by creating an account on GitHub.
github.com
'โน๏ธ ๋ผ์ดํ > 2020 ๊ฒจ์ธ๋ฐฉํ ๋ชจ๊ฐ์ฝ(๊ฐ์ธ)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [์ฝ๋ ํ๊ตฌ๋ง ํ] 2021.01.13(์) - 4์ฃผ์ฐจ ๊ฐ์ธ ๊ฒฐ๊ณผ (0) | 2021.01.13 | 
|---|---|
| [์ฝ๋ ํ๊ตฌ๋ง ํ] 2021.01.13(์) - 4์ฃผ์ฐจ ๊ฐ์ธ ๋ชฉํ (0) | 2021.01.13 | 
| [์ฝ๋ ํ๊ตฌ๋ง ํ] 2021.01.05(ํ) - 3์ฃผ์ฐจ ๊ฐ์ธ ๋ชฉํ (0) | 2021.01.05 | 
| [์ฝ๋ ํ๊ตฌ๋ง ํ] 2020.12.30(์) - 2์ฃผ์ฐจ ๊ฐ์ธ ๊ฒฐ๊ณผ (0) | 2020.12.30 | 
| [์ฝ๋ ํ๊ตฌ๋ง ํ] 2020.12.30(์) - 2์ฃผ์ฐจ ๊ฐ์ธ ๋ชฉํ (0) | 2020.12.30 |