1. 前序和中序构建二叉树
题目描述:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
1.1 递归创建
思路:
- 记录当前前序遍历和中序遍历值所在的位置;
- 对于根节点左子树来说,在中序遍历根节点的左侧,即在中序遍历数组中,其左子树继续在创建时,查看是否到了根节点值的位置;
- 对于根节点右子树来说,在中序遍历根节点的右侧,即在中序遍历数组中,其右子树继续在创建时,只需要查看是否前序遍历数组是否越界。
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return _buildTree(preorder, inorder, INT_MAX);
}
private:
TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int stop)
{
if(precur >= preorder.size())
return nullptr;
if(inorder[incur] == stop)
{
++incur;
return nullptr;
}
TreeNode* root = new TreeNode(preorder[precur++]);
root->left = _buildTree(preorder, inorder, root->val);
root->right = _buildTree(preorder, inorder, stop);
return root;
}
int precur = 0;//前序遍历的位置
int incur = 0;//中序遍历的位置
};
1.2 非递归创建
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.empty() || inorder.empty())
return nullptr;
int sz = preorder.size();
stack<TreeNode*> st;
TreeNode* root = new TreeNode(preorder[0]);
st.push(root);
int inordercur = 0;
for(int i = 1; i < sz; ++i)
{
TreeNode* node = st.top();
if(node->val != inorder[inordercur])//创建左子树
{
node->left = new TreeNode(preorder[i]);
st.push(node->left);
}
else
{
//栈顶元素和中序遍历时元素相等,说明不能再创建左子树了
//需要创建右子树,将左子树节点都pop出来
while(!st.empty() && st.top()->val == inorder[inordercur])
{
node = st.top();
st.pop();
++inordercur;
}
node->right = new TreeNode(preorder[i]);
st.push(node->right);
}
}
return root;
}
};
2. 中序和后序构建二叉树
2.1 递归创建
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
inor = inorder, post = postorder;
idx = postorder.size() - 1;
for(int i = 0; i <= idx; ++i) umap[inor[i]] = i;
return dfs(0, idx);
}
private:
vector<int> inor, post;
int idx;
unordered_map<int, int> umap;
TreeNode* dfs(int left, int right)
{
if(left > right) return nullptr;
TreeNode* root = new TreeNode(post[idx]);
int index = umap[post[idx]];
--idx;
root->right = dfs(index + 1, right);
root->left = dfs(left, index - 1);
return root;
}
};
2.2 非递归创建
class Solution {
public:
TreeNode* buildTree(vector<int>& inor, vector<int>& post) {
int n = post.size() - 1;
stack<TreeNode*> stk;
TreeNode* root = new TreeNode(post[n]);
stk.push(root);
for(int i = n - 1, j = n; i >= 0; --i)
{
auto node = stk.top();
if(node->val != inor[j])
{
node->right = new TreeNode(post[i]);
stk.push(node->right);
}
else
{
while(!stk.empty() && stk.top()->val == inor[j])
{
node = stk.top();
stk.pop();
--j;
}
node->left = new TreeNode(post[i]);
stk.push(node->left);
}
}
return root;
}
};