重建二叉树 迭代算法题解
回顾题目:力扣(LeetCode)
链接:https://leetcode.cn/problems/zhong-jian-er-cha-shu-lcof
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
示例 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
限制:
0 <= 节点个数 <= 5000
题目给出的二叉树结构如下
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
前置知识:
前序遍历:根结点 —> 左子树 —> 右子树
中序遍历:左子树—> 根结点 —> 右子树
迭代算法思路:
1.从前序和中序遍历的顺序中可以看出,如果有这样一个二叉树只有左子树,没有右子树,则前序遍历和中序遍历的结果将恰好相反。且中序遍历到的第一个数表示的是这个二叉树的最左下角的位置,而前序遍历从根节点开始,先一直遍历左子节点,直到遍历到最左下角再开始遍历右子节点。
2.用一个index指针指向中序遍历的第一个值,用一个栈来维护当前节点,先按照前序遍历将所有纯左子节点依次入栈,直至入栈的左子节点的值与中序遍历的第一个值相等,说明已经遍历至最左下角,将此时栈顶的值与index指针指向的中序遍历值相比较,如果相等则index指针加一,指向下一个中序遍历的值,栈顶节点弹出;如果不相等则说明index所指的值是一个右子节点的值,而这个右子节点的父节点就是当前栈顶的节点。
题解代码+注释
↓
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size()==0)return nullptr;//空树判断
TreeNode* root=new TreeNode(preorder[0]);//创建二叉树的根节点
stack<TreeNode*> stk;//建立stk栈用于维护逆序的左子树节点
stk.push(root);//根节点入栈
int index=0;//建立index指针用于遍历中序的值
for(int i=1;i<preorder.size();++i){
int preorderVal = preorder[i];
TreeNode* node=stk.top();//设置node为当前栈顶节点
if(node->val!=inorder[index]){//如果当前栈顶节点值不等于中序遍历的首值,说明stk栈还未到达二叉树的最左下角
node->left=new TreeNode(preorderVal);
stk.push(node->left);//新建的左子节点入栈
}else{
while(!stk.empty()&&stk.top()->val==inorder[index]){//若当前栈顶节点与inorder的值相等,则说明当前栈顶节点没有右子节点
node=stk.top();
stk.pop();
++index;
}
node->right=new TreeNode(preorderVal);//若不相等,则inorder[index]即为当前栈顶节点的右节点
stk.push(node->right);//新建的右子节点入栈
}
}
return root;
}
};