LeetCode 105 106:Construct Binary Tree from Preorder/Postorder and Inorder Traversal

LeetCode 105:

Given preorder and inorder traversal of a tree, construct the binary tree.

给定一个二叉树的前序和中序遍历,重建这棵二叉树。

LeetCode 106:

Given inorder and postorder traversal of a tree, construct the binary tree.

给定一个二叉树的后序和中序遍历,重建这棵二叉树。

两题含义差不多,我们先从105看起,105要求通过前序和中序排列重新构建二叉树。

所谓前序遍历,即先访问根节点,在依次访问左、右子树。这样根节点在二叉树前序遍历的第一个元素。元素排列为: 根、左子树、右子树

所谓中序遍历,即使先访问左子树,然后访问根节点,,再访问又子树,这样根节点位于中序遍历中间位置,左边为左子树的节点,右边为又子树的节点。元素排列为: 左子树、根、右子树。

所以通过前序后中序遍历,重建二叉树的过程如下:

1、取前序遍历的第一个节点作为根。

2、从中序遍历中查找根元素,元素左边的为左子树节点的中序遍历,右边为右子树节点的中序遍历。

3、根据左子树节点个数从前序遍历中分离出左子树的前序遍历和柚子树的前序遍历。

4、根据2、3分分解得到的左子树的前序、中序遍历递归构建左子树。根据右子树的前序、中序遍历递归构建右子树。

代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
TreeNode * helper(vector<int>& preorder, vector<int>::iterator begin1, vector<int>::iterator end1,
		vector<int>& inorder, vector<int>::iterator begin2, vector<int>::iterator end2){
		if (begin1>=end1 || begin2>=end2)
			return 0;
		//取前序遍历的第一个节点构建根节点
		int value = *begin1;
		TreeNode *pNode = new TreeNode(value);

		//在中序遍历中,根左边的为左子树节点的中序遍历,右边为右子树节点的中序遍历
		vector<int>::iterator it = find(begin2, end2, value);
		int leftLength = it - begin2;

		//在前序遍历中,除第一个元素,及根外,前leftLength个节点为左子树的前序遍历,然后是右子树的前序遍历

		//通过左子树的前序、中序遍历递归构建左子树
		pNode->left = helper(preorder, begin1+1, begin1+leftLength+1,
							 inorder, begin2, it);
		//通过右子树的前序、中序遍历递归构建右子树
		pNode->right = helper(preorder, begin1+leftLength+1, end1,
							  inorder, it+1, end2);
		return pNode;
	}

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return helper(preorder, preorder.begin(), preorder.end(), inorder, inorder.begin(), inorder.end());
    }
};

同样LeetCode 106 通过后序和中序构建二叉树的算法与之类似,只不过根节点变为后序遍历的最后一个元素。代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode * helper2(vector<int>& postorder, vector<int>::iterator begin1, vector<int>::iterator end1,
		vector<int>& inorder, vector<int>::iterator begin2, vector<int>::iterator end2){
			if (begin1>=end1 || begin2>=end2)
				return 0;
			//后序遍历,最后一个元素即为根
			int value = *(end1-1);
			TreeNode *pNode = new TreeNode(value);

           //中序遍历中,根左边的元素为左子树的中序遍历,根右边元素为右子树的中序遍历
			vector<int>::iterator it = find(begin2, end2, value);
			int leftLength = it - begin2;
            //递归构建左子树,左子树元素的后序遍历位于后序遍历的前leftLength个元素
			pNode->left = helper2(postorder, begin1, begin1+leftLength,
				inorder, begin2, it);
			//递归构建右子树,右子树元素位于后序遍历的leftLength个元素之后,根节点当然要除去
			pNode->right = helper2(postorder, begin1+leftLength, end1-1,
				inorder, it+1, end2);
			return pNode;
	}
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return helper2(postorder, postorder.begin(), postorder.end(),
		        inorder, inorder.begin(), inorder.end());
    }
};
时间: 2024-10-05 03:16:30

LeetCode 105 106:Construct Binary Tree from Preorder/Postorder and Inorder Traversal的相关文章

[Leetcode][Tree][Construct Binary Tree from Preorder/Postorder and Inorder Traversal ]

从树的中序遍历+前/后序遍历重建一棵树. 必须使用iterator才能过,否则会MLE. 1.preorder + inorder 第一个版本,使用坐标范围: 1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}

LeetCode 105/106 Construct Binary Tree from Preorder/Postorder and Inorder Traversal

一:LeetCode 105 Construct Binary Tree from Preorder and Inorder Traversal 题目: Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. 链接:https://leetcode.com/problems/co

LeetCode 106:Construct Binary Tree from Postorder and Inorder Traversal

Given inorder and postorder traversal of a tree, construct the binary tree. 给定一个二叉树的后序和中序遍历,重建这棵二叉树. 此题和LeetCode105 根据前序和中序重建二叉树类似. 所谓后序遍历,即先访问根的左.右子树,然后再访问根节点.这样根节点在二叉树后序遍历的最后一个个元素. 所谓中序遍历,即使先访问左子树,然后访问根节点,,再访问又子树,这样根节点位于中序遍历中间位置,左边为左子树的节点,右边为又子树的节点

LeetCode:Construct Binary Tree from Preorder and Inorder Traversal

要求:通过二叉树的前序和中序遍历序列构建一颗二叉树 代码如下: 1 struct TreeNode { 2 int val; 3 TreeNode *left; 4 TreeNode *right; 5 TreeNode(int x): val(x),left(NULL), right(NULL) {} 6 }; 7 8 typedef vector<int>::iterator Iter; 9 TreeNode *buildTree(vector<int> &preord

leetcode105:Construct Binary Tree from Preorder and Inorder Traversal

题目: Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that duplicates do not exist in the tree. 解题思路分析: 前序遍历首先遍历根节点,然后依次遍历左右子树 中序遍历首先遍历左子树,然后遍历根结点,最后遍历右子树 根据二者的特点,前序遍历的首节点就是根结点,然后在中序序列中找出该结点位置(index),则该结点之

[LeetCode]*105.Construct Binary Tree from Preorder and Inorder Traversal

题目 Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. 思路 主要是根据前序遍历和中序遍历的特点解决这个题目. 1.确定树的根节点.树根是当前树中所有元素在前序遍历中最先出现的元素. 2.求解树的子树.找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元

leetcode题解:Construct Binary Tree from Inorder and Postorder Traversal(根据中序和后序遍历构造二叉树)

题目: Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that duplicates do not exist in the tree. 说明: 1)实现与根据先序和中序遍历构造二叉树相似,题目参考请进 算法思想 中序序列:C.B.E.D.F.A.H.G.J.I 后序序列:C.E.F.D.B.H.J.I.G.A 递归思路: 根据后序遍历的特点,知道后序

leetcode笔记:Construct Binary Tree from Inorder and Postorder Traversal

一. 题目描述 Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. 二. 题目分析 这道题和Construct Binary Tree from Preorder and Inorder Traversal类似,都是考察基本概念的,后序遍历是先遍历左子树,然后遍历右子树,最

【leetcode刷题笔记】Construct Binary Tree from Preorder and Inorder Traversal

Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that duplicates do not exist in the tree. 类似http://www.cnblogs.com/sunshineatnoon/p/3854935.html 只是子树的前序和中序遍历序列分别更新为: //左子树: left_prestart = prestart+1 lef