04.17 重建二叉树

Posted 少年仗剑行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了04.17 重建二叉树相关的知识,希望对你有一定的参考价值。

题目:

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

示例:

preorder:[3,9,20,15,7]inorder:[9,3,15,20,7]return:  3 / \9  20  /  \ 15   7

限制:

0 <= 节点个数 <= 5000

方法1:

class Solution {public: map<int, int> index; TreeNode* build(vector<int>& preorder, vector<int>& inorder, int preLeft, int preRight, int inLeft, int inRight) { if(preLeft > preRight) // 树节点为空 return NULL; int rootIn = index[preorder[preLeft]]; // 定位中序遍历的根节点 int sizeLeft = rootIn - inLeft; // 获得左子树的节点数目 TreeNode* root = new TreeNode(preorder[preLeft]); // 构造根节点 root->left = build(preorder, inorder, preLeft + 1, preLeft + sizeLeft, inLeft, rootIn - 1); // 构造左子树 root->right = build(preorder, inorder, preLeft + sizeLeft + 1, preRight, rootIn + 1, inRight); // 构造右子树 return root; } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { int n = inorder.size(); for(int i = 0; i < n; i++) { index[inorder[i]] = i; // 构造映射,用于定位根结点 }        return build(preorder, inorder, 0, n-10, n-1); }};

方法2:

class Solution {public:    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { // 利用前序遍历和中序遍历的差异,分辨出前序遍历的左子树和右子树 if(!preorder.size()) // 树节点为空 return NULL; TreeNode* root = new TreeNode(preorder[0]); // 构造根节点 stack<TreeNode*> nodes; // 使用栈存储树节点 nodes.push(root); int inorderIndex = 0; for(int i = 1; i < preorder.size(); i++) { if(nodes.top() -> val != inorder[inorderIndex]) { // 前序遍历左子树 nodes.top() -> left = new TreeNode(preorder[i]); // 将左子树加入到根节点 nodes.push(nodes.top() -> left); } else { // 前序遍历右子树 TreeNode* node; // 记录右子树的根节点 while(!nodes.empty() && nodes.top() -> val == inorder[inorderIndex]) { node = nodes.top(); nodes.pop(); inorderIndex++; } node->right = new TreeNode(preorder[i]); // 将右子树加入到根节点 nodes.push(node -> right); } } return root; }};

以上是关于04.17 重建二叉树的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer重建二叉树

4.重建二叉树

[编程题]重建二叉树

《剑指offer》— JavaScript重建二叉树

重建二叉树

重建二叉树-剑指Offer