ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 2263 트리의 순회
    Algorithm/BOJ 2021. 3. 26. 16:19
    728x90

    출처: www.acmicpc.net/problem/2263

    분류: 트리


    접근방식

    트리 순회 방법의 특성을 잘 이용해 해결했어야 하는 문제였습니다.

    기억해야 할 특징은 다음과 같습니다.

    1. post-order는 왼쪽 - 오른쪽 - 루트 순으로 탐색하므로 배열의 마지막은 루트노드가 됩니다.

    2. in-order 는 root를 기준으로 왼쪽은 left, 오른쪽은 right 서브트리로 분리됩니다.

    post-order를 통해 root 노드를 찾았다면, in-order의 시작부터 root 까지가 왼쪽, 오른쪽으로 분리되고,

    이를 통해 왼쪽, 오른쪽에 몇 개의 노드가 존재하는지 알 수 있습니다.

    다시 in-order는 왼쪽 - 오른쪽 - 루트가 순서대로 배치되어 있기 때문에 개수를 통해 in-order에서 어디까지가 왼쪽, 오른쪽인지 알 수 있게됩니다.

    이러한 특성을 가지고 재귀적으로 탐색하면 원하는 결과를 얻을 수 있습니다.

     

    예를 들어보겠습니다. 

    다음과 같은 트리가 주어졌다면,

     

    위에 말씀드린 특성을 이용해 아래와 같이 트리의 구조를 알아낼 수가 있습니다.

    pre-order의 탐색 결과를 찾아야하므로 매번 root를 차곡차곡 담아주면 원하는 결과는 얻을 수 있게됩니다 :)

     

    해결방법

    import Foundation
    
    let n = Int(readLine()!)!
    let inOrderList = readLine()!.split(separator: " ").map { Int(String($0))! }
    var postOrderList = readLine()!.split(separator: " ").map { Int(String($0))! }
    
    var inOrderIndexTable = [Int: Int]()
    inOrderList.enumerated().forEach {
      inOrderIndexTable[$0.element] = $0.offset
    }
    
    var preOrderListResult = [String]()
    
    func makePreOrder(_ inStart: Int, _ inEnd: Int, _ postStart: Int, _ postEnd: Int) {
      guard inStart <= inEnd, postStart <= postEnd else { return }
      
      preOrderListResult.append("\(postOrderList[postEnd])")
      let rootIndexOfInOrder = inOrderIndexTable[postOrderList[postEnd]]!
      
      let leftPostCount = (rootIndexOfInOrder - inStart) - 1
      let leftPostEnd = postStart + leftPostCount
      
      // 왼쪽
      makePreOrder(inStart, rootIndexOfInOrder-1, postStart, leftPostEnd)
      // 오른쪽
      makePreOrder(rootIndexOfInOrder+1, inEnd, leftPostEnd+1, postEnd-1)
    }
    
    makePreOrder(0, inOrderList.count-1, 0, postOrderList.count-1)
    print(preOrderListResult.joined(separator: " "))

     

    배운점

    처음에 감을 잡지 못해서 다른 분들의 블로그 풀이를 참고했다.

    힌트를 얻고도 개수를 통해 다시 찾아나갈 수 있다는 걸 몰라서

    루트로 왼쪽 오른쪽 나뉘는 건 알겠는데 그다음은 어떻게 하지? 하고 한참을 고민했다.

     

    어렵다 어려워...

     

    참고

    꾸준함 - 구데타마 구데타마 님 블로그

    'Algorithm > BOJ' 카테고리의 다른 글

    백준 17136 색종이 붙이기  (0) 2021.03.28
    백준 1038 감소하는 수  (0) 2021.03.28
    백준 5639 이진 검색 트리  (0) 2021.03.26
    백준 1068 트리  (0) 2021.03.25
    백준 14503 로봇 청소기  (0) 2021.03.19

    댓글

Designed by Tistory.