假设当前前序区间为 [l, r],对应的中序区间为 [ll, rr]。由前序的性质,preorder[l] 即为当前结点值,通过中序区间找到 preorder[l] 位置的下标,结合 ll 与 rr 即可获得左右两子树的大小,从而找到下一个前序区间与中序区间。
class Solution { public: TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { if(preorder.size() == 0) return nullptr; for(int i = 0; i < inorder.size(); ++ i) map[inorder[i]] = i; return _buildTree(preorder, inorder, 0, preorder.size() - 1, 0, preorder.size() - 1); } TreeNode* _buildTree(vector<int> &preorder, vector<int> &inorder, int l, int r, int ll, int rr) { // [l, r] 前序的区间, [ll, rr] 中序的区间 if(l > r) return nullptr; TreeNode* root = new TreeNode(preorder[l], nullptr, nullptr); root -> left = _buildTree(preorder, inorder, l + 1, l + map[preorder[l]] - ll, ll, map[preorder[l]] - 1); root -> right = _buildTree(preorder, inorder, l + map[preorder[l]] - ll + 1, r, map[preorder[l]] + 1, rr); return root; } unordered_map<int, int> map; // 某个 val 在 inorder 中的下标 };