[백준 2263] 트리의 순회(Java)

최민길(Gale)·2023년 11월 23일
1

알고리즘

목록 보기
155/172

문제 링크 : https://www.acmicpc.net/problem/2263

이 문제는 트리의 성질을 이용하여 풀 수 있습니다.

이전에 풀었던 트리 문제(https://velog.io/@gale4739/%EB%B0%B1%EC%A4%80-4256-%ED%8A%B8%EB%A6%ACJava)와 유사한 듯 다르게 접근해야 합니다.

중위 순회와 후위 순회 결과가 나왔을 때 전위 순회 결과를 출력하는 문제로, 각 순회의 특징에 대해 알아야 합니다.

중위 순회의 경우 왼쪽에서 오른쪽으로 탐색하여 루트 노드값을 안다면 그 값을 기준으로 왼쪽은 왼쪽 자식 노드, 오른쪽은 오른쪽 자식 노드가 됩니다.

후위 순회의 경우 리프 노드에서 시작하여 루트 노드까지 탐색합니다. 따라서 맨 마지막에 루트 노드가 나오는 순서로 진행됩니다.

따라서 이를 동시에 적용시킨다면 다음과 같습니다.

  1. 후위 순회 결과를 탐색하면서 현재 부모 노드를 체크
  2. 부모 노드를 기준으로 중위 순회 배열을 두 개로 나눔
  3. 각각의 나눈 배열을 재귀함수를 이용하여 탐색한 결과를 트리의 자식 노드로 설정

이 때 투 포인터로 탐색하여 순회를 진행합니다. 중위 순회 배열과 후위 순회 배열 각각을 가리키는 포인터 두 개를 설정한 후 후위 순회 배열의 끝 포인터가 부모 노드를 가리키기 때문에 그 값을 출력합니다.

이 때 부모 노드가 중위 순회 배열에서 몇 번째에 위치하는지 체크한 후 왼쪽과 오른쪽으로 나누어 재귀함수를 이용하여 탐색합니다.

다음은 코드입니다.

import java.util.*;
import java.io.*;

class Main {
    static BufferedReader br;
    static int N;
    static StringBuilder sb = new StringBuilder();
    static int[] inorder, postorder;

    public static void main(String[] args) throws Exception {
        br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());

        inorder = getOrder();
        postorder = getOrder();

        preOrder(0, N - 1, 0, N - 1);
        System.out.println(sb);
    }

    static void preOrder(int is, int ie, int ps, int pe) {
        if (is > ie || ps > pe) return;

        int curr = postorder[pe];
        sb.append(curr).append(" ");

        int currIdx = getIndex(curr);
        int left = currIdx - is;

        preOrder(is, currIdx - 1, ps, ps + left - 1);
        preOrder(currIdx + 1, ie, ps + left, pe - 1);
    }

    static int getIndex(int target) {
        for (int i = 0; i < inorder.length; i++) {
            if (target == inorder[i]) return i;
        }
        return -1;
    }

    static int[] getOrder() throws Exception {
        int[] res = new int[N];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) res[i] = Integer.parseInt(st.nextToken());
        return res;
    }
}

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글

관련 채용 정보