首页 > 代码库 > LeetCode105 Construct Binary Tree from Preorder and Inorder Traversal

LeetCode105 Construct Binary Tree from Preorder and Inorder Traversal

Given preorder and inorder traversal of a tree, construct the binary tree. (Medium)

Note:
You may assume that duplicates do not exist in the tree.

 

分析:

首先考虑已知前序遍历和中序遍历的情况下,手算恢复二叉树的方法。

比如序列层序遍历为1, 23, 4567的二叉树

其前序遍历:1,2,4,5,3,6,7

中序遍历为:4,2,5,1,6,3,7

前序遍历的方式是根 左 右,所以前序遍历的第一个一定是整棵树的根节点,在中序遍历中找到这个点,即可确定左右子树的中序遍历的范围。

即1为根, 2,4,5为左子树的前序遍历, 4,2,5为左子树的中序遍历,右子树同理。

这样递归的对2,4,5的前序遍历和4,2,5的中序遍历求解,只到空节点为止,即可建立起二叉树。

代码:

首先写的时候每次递归都新建了一个vector,导致了超内存,后来改成用辅助函数添加起始终止位置即可。

两份代码都记录如下

 1 //代码1,临时vector过多而超内存
 2 class Solution {
 3 public:
 4     TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
 5         int sz = preorder.size();
 6         if (sz == 0) {
 7             return nullptr;
 8         }
 9         int rootVal = preorder[0];
10         TreeNode* root = new TreeNode(rootVal);
11         int pos;
12         for (pos = 0; pos < sz; ++pos) {
13             if (inorder[pos] == rootVal) {
14                 break;
15             }
16         }
17         if (pos < 1) {
18             root -> left = nullptr;
19         }
20         else {
21             vector<int> v1 = vector<int>(preorder.begin() + 1, preorder.begin() + pos + 1);
22             vector<int> v2 = vector<int>(inorder.begin(), inorder.begin() + pos );
23             cout << v1.size() << " " << endl;
24             root -> left = buildTree(v1, v2);            
25         }
26         if (pos + 1 >= preorder.size()) {
27             root -> right = nullptr;
28         }
29         else {
30             vector<int> v3 = vector<int>(preorder.begin() + pos + 1, preorder.end());
31             vector<int> v4 = vector<int>(inorder.begin() + pos + 1, inorder.end());
32             root -> right = buildTree(v3, v4);  
33         }
34         return root;
35     }
36 };

 

 1 //代码2,改为利用记录起始终止位置的辅助函数即可
 2 class Solution {
 3 private:
 4     TreeNode* helper(vector<int>& preorder, int prevStart, int prevEnd, vector<int>& inorder, int inStart, int inEnd) {
 5         int sz = prevEnd - prevStart;
 6         if (sz == 0) {
 7             return nullptr;
 8         }
 9         int rootVal = preorder[prevStart];
10         TreeNode* root = new TreeNode(rootVal);
11         int pos;
12         for (pos = 0; pos < sz; ++pos) {
13             if (inorder[inStart + pos] == rootVal) {
14                 break;
15             }
16         }
17         if (pos < 0) {
18             root -> left = nullptr;
19         }
20         else {
21             root -> left = helper(preorder, prevStart + 1, prevStart + pos + 1, inorder, inStart, inStart + pos);            
22         }
23         if (pos + 1 >= sz) {
24             root -> right = nullptr;
25         }
26         else {
27             root -> right = helper(preorder, prevStart + pos + 1, prevEnd, inorder, inStart + pos + 1, inEnd);  
28         }
29         return root;
30     }
31 public:
32     TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
33        return helper(preorder, 0, preorder.size(), inorder, 0, inorder.size());
34     }
35 };

 

LeetCode105 Construct Binary Tree from Preorder and Inorder Traversal