Table of contents
Construct a binary tree from preorder and inorder traversal sequences
Given two integer arrays preorder and inorder, where preorder is the preorder traversal of a binary tree and inorder is the inorder traversal of the same tree, construct a binary tree and return its root node.
Example 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
First of all, we should understand that
pre-order traversal is to traverse the root node first, then traverse the left subtree, and finally traverse the right subtree. In-order
traversal is to traverse the left subtree first, then traverse the root node, and finally traverse the right
subtree . , first traverse the left subtree, then traverse the right subtree, and finally traverse the root node
First, let's try to construct a binary tree using preorder and inorder traversal sequences
Given the preorder traversal sequence preorder and the inorder traversal sequence inorder,
we know that the preorder traversal of the binary tree must first go to the root node, so we know that the first number 3 in the preorder sequence is the root node of the binary tree, and in the inorder traversal sequence, the left The subtree must be traversed before the right subtree, so we can know that the inorder traversal sequence inorder uses the root node to divide the inorder into three intervals, (left subtree) root (right subtree), root node 3 left The element is the left subtree, and the element on the right of 3 is the right subtree
Now the left subtree of 3 is empty, and the right subtree (15, 20, 7) continues to use the same method to construct the binary tree
code:
Using recursive calls to decompose sub-problems
class Solution {
public:
TreeNode* build(vector<int>& preorder,vector<int>& inorder,
int& prev,int inbegin,int inend)
{
//perorder 前序遍历序列,inorder 中序遍历序列,prev 指向前序遍历数列下标
if(inbegin>inend)return NULL;
//当前的根节点
TreeNode* root=new TreeNode(preorder[prev]);
int rooti=inbegin; //用来查找根节点在数组中的下班位置
while(rooti<inend)
{
if(inorder[rooti]==preorder[prev])break;
rooti++;
}
prev++; //每次使用完prev需往后走,prev指的是数组前序遍历中用来判断根节点的
//划分区间,(左子树,根)根(根,右子树)
// (inbegin,rooti-1)rooti(rooti+1,inend)
//函数递归继续构造二叉树的左右节点
root->left=build(preorder,inorder,prev,inbegin,rooti-1);
root->right=build(preorder,inorder,prev,rooti+1,inend);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int i=0;
TreeNode* root=build(preorder,inorder,i,0,inorder.size()-1);
return root;
}
};
Construct binary tree from inorder and postorder traversal sequences
Given two integer arrays inorder and postorder, where inorder is the inorder traversal of a binary tree and postorder is the postorder traversal of the same tree, please construct and return this binary tree.
Example 1:
Input: inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
Output: [3,9,20,null,null,15,7]
Using the inorder and postorder traversal sequences to construct a binary tree, the root preorder and inorder sequences are similar to constructing a binary tree.
Given the inorder traversal inorder and the postorder traversal of the binary tree,
we know that the root node is traversed last in the subsequent traversal of the binary tree, so we know that the last element 3 in the postorder sequence is the root node of the binary tree. In the inorder traversal sequence, the left subtree It is better to traverse the root first, and the right subtree is traversed after the root, so we can divide the inorder sequence into three intervals according to these two conditions, (left subtree) root (right subtree), the element on the left of root node 3 is The left subtree, the element on the right of 3 is the right subtree
, there is only one left subtree sequence of 3, which is the left node of 3, and there are three elements in the right subtree sequence, which need to be further divided and repeat the above process
code:
class Solution {
public:
TreeNode* build(vector<int>& inorder, vector<int>& postorder,
int& prev,int inbegin,int inend)
{
if(inbegin>inend)return NULL;
TreeNode* root=new TreeNode(postorder[prev]);
int rooti=inbegin;
while(rooti<inend)
{
if(postorder[prev]==inorder[rooti])break;
rooti++;
}
prev--;
// (左,根)根(根,右)
//先构造右子树,再构造左子树
root->right=build(inorder,postorder,prev,rooti+1,inend);
root->left=build(inorder,postorder,prev,inbegin,rooti-1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
int i=postorder.size()-1;
TreeNode* root=build(inorder,postorder,i,0,postorder.size()-1);
return root;
}
};