티스토리 뷰
2263번: 트리의 순회
첫째 줄에 n(1≤n≤100,000)이 주어진다. 다음 줄에는 인오더를 나타내는 n개의 자연수가 주어지고, 그 다음 줄에는 같은 식으로 포스트오더가 주어진다.
www.acmicpc.net
동꿀오소리님 풀이 참고
[백준] 2263번 트리의 순회 - C++ - DGOS | 동꿀오소리
문제
donggoolosori.github.io
문제풀이
이진 트리의 인오더(중위순회)와 포스트오더(후위순회)가 주어졌을 때, 프리오더(전위순회)를 구하는 문제이다.

위 트리의 인오더, 포스트오더, 프리오더를 살펴보자.
중위 순회 : 5 6 8 4 3 1 2 7
후위 순회 : 5 8 4 6 2 1 7 3
전위 순회 : 3 6 5 4 8 7 1 2
굵게 표시해놓은 것이 루트 노드이다.
후위 순회는 [왼쪽 자식 - 오른쪽 자식 - 루트]순으로 순회하기 때문에 루트가 항상 마지막이다.
따라서 중위 순회 값의 인덱스를 따로 저장해두면 중위 순회에서의 루트 노드의 인덱스를 쉽게 찾을 수 있다.
찾아낸 루트 값을 출력해주고 더 이상 분해할 수 없을 때까지 트리의 왼쪽과 오른쪽을 탐색해주면 전위 순회를 구할 수 있다.
코드
C++ 코드
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#define MAX 100001 | |
using namespace std; | |
int in[MAX]; // inorder | |
int post[MAX]; // postorder | |
int idx[MAX]; // inorder에서 index 정보 저장 | |
// inorder 시작번호, inorder 끝번호, postorder 시작번호, postoder 끝번호 | |
void preorder(int in_left, int in_right, int po_left, int po_right) | |
{ | |
// 더 이상 분해할 수 없는 경우 종료 | |
if (in_left > in_right || po_left > po_right) return; | |
// postoder의 마지막 값이 root | |
int rootIdx = idx[post[po_right]]; | |
cout << in[rootIdx] << ' '; | |
// 왼쪽 서브트리 노드 개수 | |
int left = rootIdx - in_left; | |
// 왼쪽 | |
preorder(in_left, rootIdx - 1, po_left, po_left + left - 1); | |
// 오른쪽 | |
preorder(rootIdx + 1, in_right, po_left + left, po_right - 1); | |
} | |
int main() | |
{ | |
ios::sync_with_stdio(false); | |
cin.tie(NULL); | |
cout.tie(NULL); | |
int n; | |
cin >> n; | |
for (int i = 0; i < n; i++) cin >> in[i]; | |
for (int i = 0; i < n; i++) cin >> post[i]; | |
for (int i = 0; i < n; i++) idx[in[i]] = i; | |
//preorder(0, n, n - 1); | |
preorder(0, n - 1, 0, n - 1); | |
return 0; | |
} |
Kotlin 코드
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private var n = 0 | |
private lateinit var inorder : List<Int> | |
private lateinit var postorder : List<Int> | |
private val idx = mutableMapOf<Int, Int>() | |
fun main() = with(System.`in`.bufferedReader()) { | |
n = readLine().toInt() | |
inorder = readLine().split(" ").map { it.toInt() } | |
postorder = readLine().split(" ").map { it.toInt() } | |
inorder.forEachIndexed { index, i -> idx[i] = index } | |
preorder(0, n - 1, 0, n - 1) | |
} | |
private fun preorder(inLeft : Int, inRight : Int, postLeft : Int, postRight : Int) { | |
// 범위를 벗어난 경우 | |
if (inLeft > inRight || postLeft > postRight) return; | |
val rootIdx = idx[postorder[postRight]]!! // inorder에서 root의 위치 | |
val left = rootIdx - inLeft // 왼쪽 서브트리 노드 개수 | |
print("${postorder[postRight]} ") | |
// 왼쪽 | |
preorder(inLeft, rootIdx - 1, postLeft, postLeft + left - 1) | |
// 오른쪽 | |
preorder(rootIdx + 1, inRight, postLeft + left, postRight - 1) | |
} |
'Problem Solving > BOJ' 카테고리의 다른 글
[BOJ 4779] 칸토어 집합 C++ (0) | 2021.07.20 |
---|---|
[BOJ 4256] 트리 C++/Kotlin (0) | 2021.07.20 |
[BOJ 1074] Z C++ (0) | 2021.07.20 |
[BOJ 1655] 가운데를 말해요 C++ (0) | 2021.07.20 |
[BOJ 2696] 중앙값 구하기 C++ (0) | 2021.07.20 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Java
- 투 포인터
- 구현
- 분할 정복
- 재귀
- 두 포인터
- Two Pointer
- BOJ
- 문자열
- SWEA
- 자바
- 스택
- 배열
- 트리
- 이분 탐색
- programmers
- dfs
- 프로그래머스
- 정렬
- BFS
- 백준
- Kotlin
- 큐
- SW Expert Academy
- 알고리즘
- C++
- algorithm
- 위상 정렬
- 그래프
- 브루트포스
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함