由先序和中序重建二叉樹

由先序和中序重建二叉樹

思路:node

  前序遍歷的第一個節點就是樹的根節點,因此咱們先根據前序遍歷序列的第一個數字建立根結點,接下來在中序遍歷序列中找到根結點的位置,根節點的左邊就是左子樹,右邊就是右子樹,這樣就能肯定左、右子樹結點的數量。在前序遍歷和中序遍歷的序列中劃分了左、右子樹結點的值以後,就能夠遞歸地去分別構建它的左右子樹。ide

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    TreeNode* buildTreeCore(const vector<int>& per, int pre_start, int per_end,
                            const vector<int>& vin, int vin_start, int vin_end)
    {
        if(pre_start > per_end || vin_start > vin_end) {
            return nullptr;
        }

        TreeNode *root = new TreeNode(per[pre_start]);
        for(int i = vin_start; i <= vin_end; ++i) {
            if (per[pre_start] == vin[i]) {
                root->left = buildTreeCore(per, pre_start + 1, pre_start + i - vin_start, vin, vin_start, i - 1);
                root->right = buildTreeCore(per, pre_start + i - vin_start + 1, per_end, vin, i + 1, vin_end);
                break;
            }
        }
        return root;
    }
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if (preorder.size() != inorder.size()) {
            return nullptr;
        }

        return buildTreeCore(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1);
    }
};