Algorithm Problem 006: Construct Binary Tree from Preorder and Postorder Traversal
Problem
Problem Source:889. Construct Binary Tree from Preorder and Postorder Traversal(Daily Challenge)
Problem Description:
Given two integer arrays,
preorder
andpostorder
wherepreorder
is the preorder traversal of a binary tree of distinct values andpostorder
is the postorder traversal of the same tree, reconstruct and return the binary tree.If there exist multiple answers, you can return any of them.
Example 1:
1
2 Input: preorder = [1,2,4,5,3,6,7], postorder = [4,5,2,6,7,3,1]
Output: [1,2,3,4,5,6,7]Example 2:
1
2 Input: preorder = [1], postorder = [1]
Output: [1]Constraints:
1 <= preorder.length <= 30
1 <= preorder[i] <= preorder.length
- All the values of
preorder
are unique.postorder.length == preorder.length
1 <= postorder[i] <= postorder.length
- All the values of
postorder
are unique.- It is guaranteed that
preorder
andpostorder
are the preorder traversal and postorder traversal of the same binary tree.
Approach
Firstly, it is important to note that the binary tree constructed from preorder and postorder traversals is not unique, and therefore, there is no deterministic rule. In contrast, ‘inorder and preorder’ as well as ‘inorder and postorder’ correspond uniquely to a binary tree. These rules are clear, making coding straightforward. Hence, we need to define our own rules.
Recall that when constructing a binary tree from ‘inorder and preorder’, we sequentially traverse the preorder list. For each value, we create a corresponding node and then determine its subtree based on the inorder traversal. This can be understood as creating the preorder and verifying with the inorder.
Similarly, in this problem, we also ‘sequentially traverse the preorder list, creating a corresponding node’ but determine the position of the node (instead of its subtree) based on the postorder traversal. This is creating the preorder and verifying with the postorder.
In preorder, the sequence is “root - left - right”, and for each node in preorder, we can try placing it as the left child. In postorder, the sequence is “left - right - root”. If a node A in postorder is after node B, then A cannot be in the left subtree of B.
For example, consider node 5
in Example 1. While sequentially traversing the preorder list, we can try placing 5
as the left child of 4
. However, in the postorder list, since 5
comes after 4
, this attempt is not allowed. 5
can only be in the right subtree of one of the ancestors of 4
, in this case, the right child of 2
.
Therefore, we need to keep track of the path from the root to the last traversed node and store them in a stack.
- As long as the current node and the top node of the stack do not satisfy the postorder constraint mentioned above, we pop the stack until it is satisfied. At this point, the current node becomes the right child of the top node.
- If the constraint is already satisfied, the current node directly becomes the left child of the top node.
Code
The above approach is a rough description, and we should pay attention to details.
1 | /** |
Time Complexity: $O(n)$
- Sequentially traverse
preorder
andpostorder
. - Each node enters and exits
ve
only once.
Space Complexity: $O(n)$
mp
stores the values and their indices of all $n$ nodes.- In the worst case, all nodes are in
ve
.