剑指Offer总结——重建二叉树

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        int len = pre.size();
        if(len==0) {
            return nullptr;
        }
        int root = pre[0];
        vector<int> leftPre, leftIn, rightPre, rightIn;
        TreeNode *ret = new TreeNode(root);
        int inRootIdx = 0;
        
        for(inRootIdx=0; inRootIdx < len; ++inRootIdx) {
            if(vin[inRootIdx] == root) {
                break;
            }
        }
        
        for(int i=0; i < len; ++i) {
            if(i < inRootIdx) {
                leftPre.push_back(pre[i+1]);
                leftIn.push_back(vin[i]);
            }
            else if(i>inRootIdx) {
                rightPre.push_back(pre[i]);
                rightIn.push_back(vin[i]);
            }
        }
        ret->left = reConstructBinaryTree(leftPre, leftIn);
        ret->right = reConstructBinaryTree(rightPre, rightIn);
        return ret;
    }
};

这里是一种递归的思路,就是每次都把数组分割成3个部分,根、左子树、右子树。原理是,前序遍历的顺序是根左右,中序遍历的顺序是左根右,所以如果前序结果为{1,2,4,7,3,5,6,8},中序结果为{4,7,2,1,5,3,8,6},那么首先可以确定,根节点是1(题目默认不存在重复的值)。

其次,可以依靠中序遍历确定,根节点1的左边都是左子树,右边都是右子树(因为中序遍历顺序就是左根右,左子树具体怎么样的待会处理,这里先同意看作“左子树”)。所以我们可以在确定了哪部分是左子树哪部分是右子树之后递归处理。

posted @ 2019-11-25 16:44  夜溅樱  阅读(160)  评论(0编辑  收藏  举报