알고리즘/프로그래머스
[프로그래머스] 2019 KAKAO BLIND RECRUITMENT 길 찾기 게임 by 파이썬 (Python) : 트리 순회
코딩하는이씨
2023. 7. 28. 17:49
728x90
반응형
https://school.programmers.co.kr/learn/courses/30/lessons/42892?language=python3
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
난이도
LV3
문제 설명
노드들이 좌표값으로 주어지고 이진트리를 만들어 전위 순회, 후위순회 결과를 Return해야한다.
아래의 규칙들로 트리 노드를 구성한다.
- 트리를 구성하는 모든 노드의 x, y 좌표 값은 정수이다.
- 모든 노드는 서로 다른 x값을 가진다.
- 같은 레벨(level)에 있는 노드는 같은 y 좌표를 가진다.
- 자식 노드의 y 값은 항상 부모 노드보다 작다.
- 임의의 노드 V의 왼쪽 서브 트리(left subtree)에 있는 모든 노드의 x값은 V의 x값보다 작다.
- 임의의 노드 V의 오른쪽 서브 트리(right subtree)에 있는 모든 노드의 x값은 V의 x값보다 크다.
접근법
solution
- 각 인덱스+1번(노드번호)순서로 좌표값이 주어지는데 정렬시 인덱스가 달라지므로 인덱스+1(노드번호)을 각 좌표값 뒤에 추가 해준다.
- 루트 값을 구하기 위해 Y축 기준으로 내림차순 정렬한 배열(top)을 만든다. top[0]이 루트 노드가 된다.
- X축을 기준으로 오름차순 정렬한 배열 (left)을 만든다 left[0]이 가장 왼쪽에 있는 노드가 된다.
- preorder, posrtoder을 실행한다.
- 두 실행한 결과 값을 Return해준다.
preorder
- Y축기준 내림차순 정렬된 배열을 이용해 루트노드를 저장한다.
- X축 기준 오름차순 정렬된 배열에서 해당 루트노드의 index번호 를 찾아 저장한다. (해당 인덱스 번호 기준 왼쪽, 오른쪽 노드 구분 가능)
- 루트 노드 top[0]번을 제외한 1번 부터 X축값을 비교한다.
- X축값이 루트노드보다 작다면 (루트노드 왼쪽에 존재) arr_left(왼쪽배열)에 저장한다.
- X축 값이 루트 노드보다 크다면 (루트노드 오른쪽에 존재) arr_right(오른쪽배열)에 저장한다.
- 루트 노드의 번호를 저장해준다.
- arr_left의 배열에 값이 있다면 루트노드의 index번호 왼쪽 배열에 대해 재귀함수를 호출한다.
- arr_right의 배열에 값이 있다면 루트노드의 index번호 오른쪽 배열에 대해 재귀함수를 호출한다.
postorder
- Y축기준 내림차순 정렬된 배열을 이용해 루트노드를 저장한다.
- X축 기준 오름차순 정렬된 배열에서 해당 루트노드의 index번호 를 찾아 저장한다. (해당 인덱스 번호 기준 왼쪽, 오른쪽 노드 구분 가능)
- 루트 노드 top[0]번을 제외한 1번 부터 X축값을 비교한다.
- X축값이 루트노드보다 작다면 (루트노드 왼쪽에 존재) arr_left(왼쪽배열)에 저장한다.
- X축 값이 루트 노드보다 크다면 (루트노드 오른쪽에 존재) arr_right(오른쪽배열)에 저장한다.
- arr_left의 배열에 값이 있다면 루트노드의 index번호 왼쪽 배열에 대해 재귀함수를 호출한다.
- arr_right의 배열에 값이 있다면 루트노드의 index번호 오른쪽 배열에 대해 재귀함수를 호출한다.
- 루트 노드의 번호를 저장해준다.
코드
import sys
sys.setrecursionlimit(10**6)
def preorder(top, left, fanswer):
n = top[0] # 루트노드 저장
index = left.index(n) #중심 노드 지정
arr_left, arr_right =[] , []
for i in range(1, len(top)):
if n[0] > top[i][0]: #X값 비교해서 작으면 왼쪽
arr_left.append(top[i])
else:
arr_right.append(top[i])
fanswer.append(n[2]) #루트 노드 번호 저장
if len(arr_left) > 0:
preorder(arr_left, left[:index], fanswer)
if len(arr_right) > 0:
preorder(arr_right, left[index+1:], fanswer)
def postorder(top, left, sanswer):
n = top[0]
index = left.index(n)
arr_left, arr_right =[] , []
for i in range(1, len(top)):
if n[0] > top[i][0]: #X값 비교해서 작으면 왼쪽
arr_left.append(top[i])
else:
arr_right.append(top[i])
if len(arr_left) > 0:
postorder(arr_left, left[:index], sanswer)
if len(arr_right) > 0:
postorder(arr_right, left[index+1:], sanswer)
sanswer.append(n[2])
def solution(nodeinfo):
fanswer, sanswer = [], []
for i in range(len(nodeinfo)):
nodeinfo[i].append(i+1)
top = sorted(nodeinfo, key = lambda x : (-x[1],x[0])) #루트노드부터 정렬
left = sorted(nodeinfo) #왼쪽부터 정렬
preorder(top, left, fanswer)
postorder(top, left, sanswer)
return [fanswer, sanswer]
트리 순회?
[트리 순회] 알고리즘 - 트리 순회
트리 순회 트리 구조에서 각각의 노드를 정확히 한 번만 체계적인 방법으로 방문하는 과정을 말한다. 순회의 종류 전위 순회(preorder) : 뿌리(root)를 먼저 방문한다. 중위 순회(inorder) : 왼쪽 하위
h-castle.tistory.com
728x90
반응형