【剑指offer】面试题07.重建二叉树

6.24更新

前序+中序

class Solution {
public:
    vector<int> pre, in;
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if (preorder.empty() || inorder.empty()) return nullptr;//判断是否为空
        pre = preorder;
        in = inorder;
        return rebuild(0, pre.size() - 1, 0, in.size() - 1);
    }
    TreeNode* rebuild(int preL, int preR, int inL,int inR) {
        if (preL > preR) return nullptr;//递归边界
        int k;//在中序遍历中的根节点的索引
        for (k = inL; k <= inR; k++) {//计算k
            if(in[k]==pre[preL]) break;
        }
		int numLeft = k - inL;//左节点个数
        TreeNode* root = new TreeNode(in[k]);//新建一个节点作为其根节点
        root->left = rebuild(preL + 1, preL + numLeft, inL, k-1);//对其左子树进行重建
        root->right = rebuild(preL + numLeft + 1, preR, k + 1, inR);//对其右子树进行重建
        return root;//返回根节点
    }
};

后序+中序

class Solution {
public:
	vector<int> in, post;
	TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
		if (inorder.empty() || postorder.empty()) return nullptr;
		in = inorder;
		post = postorder;
		return rebuild(0, post.size() - 1, 0, in.size() - 1);
	}
	TreeNode* rebuild(int postL, int postR, int inL, int inR) {
		if (postL > postR) return nullptr;
		int k;
		for (k = inL; k <= inR; k++) {
			if(in[k]==post[postR]) break;
		}
		int numRight = inR-k;//右子节点的个数
		TreeNode* root = new TreeNode(in[k]);
		root->left = rebuild(postL, postR-numRight-1, inL, k - 1);
		root->right = rebuild(postR-numRight,postR-1,k + 1, inR);
		return root;
	}
};

2.24

代码

class Solution {
public:
	TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
		return create(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
	}
	TreeNode* create(vector<int>& preorder, vector<int>& inorder, int preL, int preR, int inL, int inR)
	{
		//递归边界
		if (preL > preR) return NULL;

		TreeNode* head = new TreeNode(preorder[preL]);//创建节点并赋值

		//先序遍历的头节点在中序遍历中的位置
		int k;
		for (k = inL; k <= inR; k++)
		{
			if (preorder[preL] == inorder[k])
			{
				break;
			}
		}
		//左子树结点的个数,方便区间的填写
		int numsLeft = k - inL;
		//对于head的左子树继续构建
		head->left = create(preorder, inorder, preL + 1, preL + numsLeft, inL, inL + k - 1);
		//对于head的右子树继续构建
		head->right = create(preorder, inorder, preL +numsLeft+1, preR, k + 1, inR);
		//返回根结点地址
		return head;
	}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值