1. 문제 설명
라이언은 아래와 같은 특별한 규칙으로 트리 노드들을 구성한다.
- 트리를 구성하는 모든 노드의 x, y 좌표 값은 정수이다.
- 모든 노드는 서로 다른 x값을 가진다.
- 같은 레벨(level)에 있는 노드는 같은 y 좌표를 가진다.
- 자식 노드의 y 값은 항상 부모 노드보다 작다.
- 임의의 노드 V의 왼쪽 서브 트리(left subtree)에 있는 모든 노드의 x값은 V의 x값보다 작다.
- 임의의 노드 V의 오른쪽 서브 트리(right subtree)에 있는 모든 노드의 x값은 V의 x값보다 크다.
이진트리를 구성하는 노드들의 좌표가 담긴 배열 nodeinfo가 매개변수로 주어질 때,
노드들로 구성된 이진트리를 전위 순회, 후위 순회한 결과를 2차원 배열에 순서대로 담아 return
제한사항
- nodeinfo는 이진트리를 구성하는 각 노드의 좌표가 1번 노드부터 순서대로 들어있는 2차원 배열이다.
- nodeinfo의 길이는 1 이상 10,000 이하이다.
- nodeinfo[i] 는 i + 1번 노드의 좌표이며, [x축 좌표, y축 좌표] 순으로 들어있다.
- 모든 노드의 좌표 값은 0 이상 100,000 이하인 정수이다.
- 트리의 깊이가 1,000 이하인 경우만 입력으로 주어진다.
- 모든 노드의 좌표는 문제에 주어진 규칙을 따르며, 잘못된 노드 위치가 주어지는 경우는 없다.
2. 풀이 전 계획과 생각
- 트리를 만들어, 전위 순회 후위순회를 하는 문제다.
- 트리를 만들 때 필요한 값은 각 노드마다 해당 값과 left Node, right Node이며,
삽입하면서 트리를 구성해주면 된다. - y값이 작은 순, x값 작은 순으로 정렬 해야 문제에 제시한 규칙대로 트리 노드를 구성해줄 수 있다.
- 처음 루트 노드를 삽입하고 그다음 정렬된 값들을 가지고 삽입해준다.
- 트리에서 노드를 삽입하는 과정은 루트에서 시작해서
left 노드와 right 노드를 계속 비교해주면서 삽입하면 된다.
계속 비교해주기 위해 부모 노드와 자식 노드를 가지고 재귀적으로 내려가서 비교하면된다.
정렬 후, 0번 인덱스 값을 root로 지정한다.
root를 기준으로 노드들을 insert 한다.
root보다 x값이 더 작다면 왼쪽으로, 더 크다면 오른쪽으로 insert 해주었다.
이때 이미 왼쪽, 오른쪽 자식이 존재하면 자식의 값과 재귀적으로 비교하여 적절한 위치를 찾아 insert 해주자.
3. 풀이
import sys
sys.setrecursionlimit(1000 * 10000)
class Node:
def __init__(self, x, y, value):
self.x = x
self.y = y
self.value = value
self.left = None
self.right = None
class Tree:
def __init__(self, x, y, value):
self.root = Node(x, y, value)
def insert(self, parent, child):
if parent.x > child.x:
if parent.left == None:
parent.left = child
else:
self.insert(parent.left, child)
else:
if parent.right == None:
parent.right = child
else:
self.insert(parent.right, child)
def preorder(current):
global answer
if current != None:
answer[0].append(current.value)
preorder(current.left)
preorder(current.right)
def postorder(current):
global answer
if current != None:
postorder(current.left)
postorder(current.right)
answer[1].append(current.value)
answer = [[], []]
def solution(nodeinfo):
global answer, idx
nodes = [[i + 1, nodeinfo[i]] for i in range(len(nodeinfo))]
nodes.sort(key=lambda x: [-x[1][1], x[1][0]])
tree = Tree(nodes[0][1][0], nodes[0][1][1], nodes[0][0])
for idx in range(1, len(nodeinfo)):
tree.insert(tree.root, Node(nodes[idx][1][0], nodes[idx][1][1], nodes[idx][0]))
root = tree.root
preorder(root)
postorder(root)
return answer
4. 풀이 후 알게된 개념과 소감
- 트리는 노드를 탐색할 때, 재귀적으로 내려가서 탐색하는 자료구조다. (노드 삽입, 삭제도 마찬가지다.)
- 순회
- 중위 순회 (Inorder Traversal) : left → root → right
- 전위 순회 (Preorder Traversal) : root → left → right
- 후위 순회 (Postorder Traversal) : left → right → root
'Problem Solving' 카테고리의 다른 글
[백준] 1726 : 로봇 / python (0) | 2022.09.01 |
---|---|
[백준] 3190 : 뱀 (삼성 SW 역량 테스트) / python (0) | 2022.08.20 |
[프로그래머스] 자물쇠와 열쇠 (2020 KAKAO BLIND) / python (0) | 2022.08.15 |
[프로그래머스] 순위 검색 (2021 KAKAO BLIND) / python (0) | 2022.08.12 |
[프로그래머스] 광고 삽입 (2021 KAKAO BLIND) / python (0) | 2022.08.05 |