leetcode.105 & 106 基于(前序/后序)和中序 遍历结果 重建二叉树

105 和 106 涉及通过中序遍历结果,配合前序或后序遍历结果来重建原来的二叉树。问题不难,在学习树的遍历的时候,其实应该学会如何解决这种问题。

这类问题的核心思路在于:

  • 基于前序,推断出根节点。这是因为前序遍历的过程是,先访问根节点,再访问左子树,最后访问右子树。而后序遍历的过程是先访问左子树,再访问右子树,最后访问根。
  • 找到根节点后,再通过中序遍历的结果,找到根在中序遍历中的位置 i i 。那么位置i之前的就是这个根的所有左子树的节点,i之后就是所有右子树的节点。同时也能够确定左右子树的前序遍历结果。
  • 递归的重建左右子树
  • 把左右子树挂在根上。

代码:
leetcode 105:

class Solution {
public:
	TreeNode * build(vector<int> & preorder, vector<int> &inorder, int pl, int pr,int il,int ir)
	{
		if (pl >= pr)
		{
			return NULL;
		}
		if (il >= ir)
		{
			return NULL;
		}
		int i;
		TreeNode * node=NULL;
		for (i = il; i < ir; i++)
		{
			if (preorder[pl] == inorder[i])
			{
				node = new TreeNode(preorder[pl]);
				//找到了Head
				break;
			}
		}
		if (node == NULL) return NULL;
		//处理左边
		TreeNode * left = build(preorder, inorder, pl + 1, pl + i-il +1 , il, i);
		//处理右边
		TreeNode * right = build(preorder, inorder, pl + i-il +1,pr,i+1 ,ir );
		node->left = left;
		node->right = right;
		return node;

	}
	TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
	{
		return build(preorder, inorder, 0, preorder.size(), 0, inorder.size());
	}

};

leetcode 106:

class Solution {
public:
	TreeNode * build(vector<int> & inorder, vector<int> &postorder, int il, int ir, int pl, int pr)
	{
		if (pl > pr) return NULL;
		if (il > ir) return NULL;
		TreeNode * head = NULL;
		int i;
		for ( i =il;i<=ir;i++)
		{
			if (inorder[i] == postorder[pr])
			{
				head = new TreeNode(inorder[i]);
				break;
			}
		}
		if (head == NULL) return NULL;
		TreeNode *right = build(inorder,postorder,i+1,ir,pl+i-il,pr-1);
		TreeNode *left = build(inorder,postorder,il,i-1,pl,pl+i-il -1);
		head->left = left;
		head->right = right;
		return head;
	}
	TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
	{
		return build(inorder, postorder, 0, inorder.size()-1, 0, postorder.size()-1);
	}

};
发布了307 篇原创文章 · 获赞 268 · 访问量 56万+

猜你喜欢

转载自blog.csdn.net/jmh1996/article/details/102529342