这道题自己写出来的,还是用递归的办法来做,对于前序遍历的数组preorder
,第一个元素肯定是根节点,我们就直接将preorder[0]
设置为根节点的值,由于题目中说了preorder
和inorder
没有重复元素,所以我们直接在inorder
中找到与preorder[0]
相等的元素的下标i
,则inorder[0]
到inorder[i - 1]
都是左子树的元素,而inorder[i + 1]
到inorder[inorder.size() - 1]
都是右子树的元素。我们还可以知道,左子树共有i
个元素,右子树共有inorder.size() - i - 1
或preorder.size() - i - 1
个元素,因此我们也可以得到前序遍历的左子树部分为preorder[1]
到preorder[i]
的元素,而前序遍历的右子树部分为preorder[i + 1]
到preorder[preorder.size() - 1]
的元素,这样,我们可以通过迭代器构造的方式分别将左子树的前序和中序遍历的数组,右子树的前序和中序遍历的数组构造出来,然后我们只需要递归调用buildTree()
分别构造左子树和右子树即可,当然,递归的终止条件是当传入的数组为空,此时返回空指针。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
//递归终止条件
if(preorder.empty() || inorder.empty())
return nullptr;
TreeNode* root = new TreeNode(preorder[0]);
int i;
for(i = 0; inorder[i] != root -> val; i++);
vector<int> left_tree_pre(preorder.begin() + 1, preorder.begin() + 1 + i); //前序数组的左子树元素
vector<int> right_tree_pre(preorder.begin() + 1 + i, preorder.end()); //前序数组的右子树元素
vector<int> left_tree_in(inorder.begin(), inorder.begin() + i); //中序数组的左子树元素
vector<int> right_tree_in(inorder.begin() + 1 + i, inorder.end()); //前序数组的右子树元素
root -> left = buildTree(left_tree_pre, left_tree_in);
root -> right = buildTree(right_tree_pre, right_tree_in);
return root;
}
};