Leetcode 105&106

Leetcode 105 & 106

Quetion 105

Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.

Quetion 106

Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.

这两道题类似,都是根据树的遍历来重建一棵树。

先复习下先序中序后序:先序根左右,中序左根右,后序左右根,区别是根的出现的顺序。一开始想着用传vector的方法,但是后来发现内存爆了,用索引的方法更好, 因为只遍历了一次整个vector所以时间复杂度为O(n)

说下105即根据先序中序遍历来重建一棵树的做法:因为先序的第一个元素是根,然后在中序遍历中找到这个根。然后在中序的遍历元素中,根左边的那些元素是根的左子树,右边是右子树,然后根据左右子树的长度在前序中区分出左右子树,继续往下建树。比较难的一点就在于区分出这个边界。代码如下:

class Solution {
public:
TreeNode* createNode(vector<int>& preOrder, vector<int>& inOrder, int startPre, int endPre, int startIn, int endIn) {
    if (startPre > endPre || startIn > endIn)
        return NULL;
    int root = preOrder[startPre], index;
    for (index = startIn; index <= endIn; index++) {
        if (inOrder[index] == root)
            break;
    }
    TreeNode* res = new TreeNode(root);
    res->left = createNode(preOrder, inOrder, startPre + 1, startPre + 1 + (index - 1 - startIn), startIn, index - 1);
    res->right = createNode(preOrder, inOrder, startPre + 1 + (index - startIn), endPre, index + 1, endIn);
    return res;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    TreeNode* res = createNode(preorder, inorder, 0, preorder.size() - 1, 0, preorder.size() - 1);
    return res;
}
};

106是根据后序中序来重建一棵树,过程相似,后序遍历的最后一个元素是根,然后在中序中找出这个根,中序中根的左边是左子树,右边是右子树,然后相似的重建这棵树,同样要区分出边界,代码如下:

class Solution {
public:
    TreeNode* createNode(vector<int>& inorder, vector<int>& postorder, int startIn, int endIn, int startPost, int endPost) {
    if (startIn > endIn || startPost > endPost) {
        return NULL;
    }
    // 后序的最后一个表示的是根节点
    int root = postorder[endPost], index = startIn;
    TreeNode* p = new TreeNode(root);
    for (index; index <= endIn; index++) {
        if (inorder[index] == root) {
            break;
        }
    }
        p->left = createNode(inorder, postorder, startIn, index - 1, startPost, startPost + index - 1 - startIn);
        p->right = createNode(inorder, postorder, index + 1, endIn, endPost - 1 - (endIn -index - 1), endPost - 1);
    return p;

    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        TreeNode* res;
        res = createNode(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1);
        return res;
    }
};

最后贴个别人写的一个更好的代码,思路相似,但是是先建好右子树,然后index不断移动,再到建立左子树:

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if (inorder.empty() || postorder.empty())
            return NULL;
        int root_index = postorder.size()-1;
        return createBST(inorder,postorder,0,root_index,root_index);
    }
    TreeNode* createBST(vector<int>& inorder, vector<int>& postorder, int start, int end, int& index) {
        int v = postorder[index];
        int i = end;
        for (i; i >= start; i--)
            if (inorder[i] == v)
                break;
        TreeNode* root = new TreeNode(v);
        if (end >= i+1)
            root->right = createBST(inorder,postorder,i+1,end,--index);
        if (i-1 >= start)
            root->left = createBST(inorder,postorder,start,i-1,--index);

        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值