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 };