构建二叉树

1. 前序和中序构建二叉树

题目描述:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

leetcode链接
在这里插入图片描述

1.1 递归创建

思路:

  1. 记录当前前序遍历和中序遍历值所在的位置;
  2. 对于根节点左子树来说,在中序遍历根节点的左侧,即在中序遍历数组中,其左子树继续在创建时,查看是否到了根节点值的位置;
  3. 对于根节点右子树来说,在中序遍历根节点的右侧,即在中序遍历数组中,其右子树继续在创建时,只需要查看是否前序遍历数组是否越界。
class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return _buildTree(preorder, inorder, INT_MAX);
    }

private:
    TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int stop)
    {
        if(precur >= preorder.size())
            return nullptr;
        if(inorder[incur] == stop)
        {
            ++incur;
            return nullptr;
        }

        TreeNode* root = new TreeNode(preorder[precur++]);
        root->left = _buildTree(preorder, inorder, root->val);
        root->right = _buildTree(preorder, inorder, stop);

        return root;
    }

    int precur = 0;//前序遍历的位置
    int incur = 0;//中序遍历的位置
};

1.2 非递归创建

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.empty() || inorder.empty())
            return nullptr;
        int sz = preorder.size();

        stack<TreeNode*> st;
        TreeNode* root = new TreeNode(preorder[0]);
        st.push(root);
        int inordercur = 0;

        for(int i = 1; i < sz; ++i)
        {
            TreeNode* node = st.top();
            if(node->val != inorder[inordercur])//创建左子树
            {
                node->left = new TreeNode(preorder[i]);
                st.push(node->left);
            }
            else 
            {
				//栈顶元素和中序遍历时元素相等,说明不能再创建左子树了
				//需要创建右子树,将左子树节点都pop出来
                while(!st.empty() && st.top()->val == inorder[inordercur])
                {
                    node = st.top();
                    st.pop();
                    ++inordercur;
                }

                node->right = new TreeNode(preorder[i]);
                st.push(node->right);
            }
        }

        return root;
    }
};

2. 中序和后序构建二叉树

leetcode地址

2.1 递归创建

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {

        inor = inorder, post = postorder;
        idx = postorder.size() - 1;
        for(int i = 0; i <= idx; ++i) umap[inor[i]] = i;

        return dfs(0, idx);
    }
private:
    vector<int> inor, post;
    int idx;
    unordered_map<int, int> umap;

    TreeNode* dfs(int left, int right)
    {
        if(left > right) return nullptr;

        TreeNode* root = new TreeNode(post[idx]);

        int index = umap[post[idx]];
        --idx;
        
        root->right = dfs(index + 1, right);
        root->left = dfs(left, index - 1);
        

        return root;
    }
};

2.2 非递归创建

class Solution {
public:
    TreeNode* buildTree(vector<int>& inor, vector<int>& post) {

        int n = post.size() - 1;
        stack<TreeNode*> stk;
        TreeNode* root = new TreeNode(post[n]);
        stk.push(root);

        for(int i = n - 1, j = n; i >= 0; --i)
        {
            auto node = stk.top();
            if(node->val != inor[j])
            {
                node->right = new TreeNode(post[i]);
                stk.push(node->right);
            }
            else
            {
                while(!stk.empty() && stk.top()->val == inor[j])
                {
                    node = stk.top();
                    stk.pop();
                    --j;
                }

                node->left = new TreeNode(post[i]);
                stk.push(node->left);
            }
        }

        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值