【剑指offer】21.重建二叉树
总目录:
1.问题描述
给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}。
提示:
1.vin.length == pre.length 
2.pre 和 vin 均无重复元素 
3.vin出现的元素均出现在 pre里 
4.只需要返回根结点,系统会自动输出整颗树做答案对比 
数据范围:n≤2000n≤2000,节点的值 −10000≤val≤10000−10000≤val≤10000 
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n) 
2.问题分析
1递归,
(1)前序遍历第一个就是根节点,
(2)中序遍历中,在根节点左边的(假设有x个)属于根节点的左子树,在根节点右边的(假设有y个)属于根节点的右子树,生成pre_left和pre_right
(3)在前序遍历中,根节点后面x个属于根节点的左子树,左子树部分后面剩余部分属于右子树;生成vin_left和vin_right
(4)通过2和3的切割,逐层递归完成子树的重建,挂在根节点的左右子树上;
3.代码实例
递归
 
1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) { 13 //中止条件 14 int nodeNumInTree = pre.size(); 15 if (nodeNumInTree <= 0) { //pre.length=vin.length 16 return NULL; 17 } 18 19 //本层逻辑 20 //先序遍历第一个是根节点 21 TreeNode* root = new TreeNode(pre[0]); 22 23 //获得根节点在中序遍历中的索引,以便切割pre和vin 24 int rootIndex = 0; 25 for (rootIndex = 0; rootIndex < nodeNumInTree; rootIndex++) { 26 if (vin[rootIndex] == pre[0]) { 27 break; 28 } 29 } 30 31 //切割 32 vector<int> pre_left, pre_right, vin_left, vin_right; 33 for (int i = 0; i < rootIndex; i++) { 34 pre_left.push_back(pre[i + 1]); //跳过根节点 35 vin_left.push_back(vin[i]); 36 } 37 for (int i = rootIndex + 1; i < nodeNumInTree; i++) { 38 pre_right.push_back(pre[i]); 39 vin_right.push_back(vin[i]); 40 } 41 42 //调用递归 43 root->left = reConstructBinaryTree(pre_left, vin_left); 44 root->right = reConstructBinaryTree(pre_right, vin_right); 45 46 return root; 47 } 48 };
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号