|
| 1 | +package leetcode_study |
| 2 | + |
| 3 | +import io.kotest.matchers.equals.shouldBeEqual |
| 4 | +import org.junit.jupiter.api.Test |
| 5 | + |
| 6 | +class `construct-binary-tree-from-preorder-and-inorder-traversal` { |
| 7 | + |
| 8 | + /** |
| 9 | + * preorder : 현재(부모) 노드부터 왼쪽 자식 노드, 오른쪽 자식 노드 |
| 10 | + * inorder : 왼쪽 자식 노드 부터 부모 노드, 오른쪽 자식 노드 |
| 11 | + */ |
| 12 | + fun buildTree(preorder: IntArray, inorder: IntArray): TreeNode? { |
| 13 | + val inorderIndices = inorder.withIndex().associate { it.value to it.index } |
| 14 | + return traversal(preorder, inorder, inorderIndices) |
| 15 | + } |
| 16 | + |
| 17 | + /** |
| 18 | + * preorder에서 조회한 부모 노드의 값은 inorder의 중간에 위치한다. |
| 19 | + * 그 중간 위치 기준으로 왼쪽 노드, 오른쪽 노드로 분리하여 재귀적으로 탐색할 수 있다. |
| 20 | + * 시간복잡도: O(n), 공간복잡도: O(n) |
| 21 | + */ |
| 22 | + private fun traversal( |
| 23 | + preorder: IntArray, inorder: IntArray, inorderIndices: Map<Int, Int>, |
| 24 | + preStart: Int = 0, inStart: Int = 0, inEnd: Int = inorder.size - 1 |
| 25 | + ): TreeNode? { |
| 26 | + if (preStart > preorder.size - 1 || inStart > inEnd) { |
| 27 | + return null |
| 28 | + } |
| 29 | + val value = preorder[preStart] |
| 30 | + val rootIndexInInorder = inorderIndices[value]!! |
| 31 | + |
| 32 | + return TreeNode(value).apply { |
| 33 | + this.left = traversal( |
| 34 | + preorder, inorder, inorderIndices, |
| 35 | + preStart + 1, inStart, rootIndexInInorder - 1 |
| 36 | + ) |
| 37 | + this.right = traversal( |
| 38 | + preorder, inorder, inorderIndices, |
| 39 | + preStart + rootIndexInInorder - inStart + 1, rootIndexInInorder + 1, inEnd |
| 40 | + ) |
| 41 | + } |
| 42 | + } |
| 43 | + |
| 44 | + @Test |
| 45 | + fun `전위 순회, 중위 순회 순서의 정수 배열을 기준으로 이진트리를 생성하여 반환한다`() { |
| 46 | + val actual = buildTree(intArrayOf(3,9,20,15,7), intArrayOf(9,3,15,20,7))!! |
| 47 | + val expect = TreeNode.of(3,9,20,null,null,15,7)!! |
| 48 | + |
| 49 | + actual shouldBeEqual expect |
| 50 | + |
| 51 | + val actual1 = buildTree(intArrayOf(3,9,8,10,20,15,7), intArrayOf(8,9,10,3,15,20,7))!! |
| 52 | + val expect1 = TreeNode.of(3,9,20,8,10,15,7)!! |
| 53 | + |
| 54 | + actual1 shouldBeEqual expect1 |
| 55 | + } |
| 56 | +} |
0 commit comments