【LeetCode & 剑指offer刷题】树题12:7 重建二叉树(系列)
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
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.
For example, given
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
Return the following binary tree:
3
/ \
9 20
/ \
15 7
/**
* 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* buildTree(vector<int>& preorder, vector<int>& inorder)
{
return buildOneLevel(preorder, 0, preorder.size()-1,inorder, 0 ,inorder.size()-1);
}
//递归函数功能:构建树的某一层结构
TreeNode* buildOneLevel(vector<int>& preorder, int pre_begin, int pre_end, vector<int>& inorder, int in_begin, int in_end)//这里用下标法,需要6个形参,也可以用迭代器只需4个形参
{
if(pre_begin>pre_end || in_begin>in_end) return NULL; //递归子函数的出口
//先找根节点(用前序遍历序列)
TreeNode* root = new TreeNode(preorder[pre_begin]);
//在找左子树和右子树(用中序遍历序列)
int left_length = 0; //左子树长度
for(int i = in_begin; i<= in_end; i++)
{
if(inorder[i] == root->val)
{
left_length = i;
break; //先找到中序遍历序列中根节点的位置
}
}
left_length -= in_begin; //左子树长度
root->left = buildOneLevel(preorder, pre_begin+1, pre_begin+left_length, inorder, in_begin, in_begin+left_length-1);//左子树
root->right = buildOneLevel(preorder, pre_begin+left_length+1, pre_end, inorder,in_begin+left_length+1,in_end); //右子树
return root; //递归母函数的出口
}
};*/
#include <algorithm>
class
Solution
{
public
:
TreeNode
*
buildTree
(
vector
<
int
>&
preorder
,
vector
<
int
>&
inorder
)
{
return
buildOneLevel
(
preorder
.
begin
(),
preorder
.
end
(),
inorder
.
begin
(),
inorder
.
end
());
//!!注意end指向容器末尾(最后一个元素的下一个位置)
}
//递归函数功能:构建树的某一层结构
// template<typename iterator> //也可直接用vector<int>::iterator类型,模板可以进行类型延伸(泛型编程),避免不同类型写多个函数(自己的思考),但函数内部的很多变量名需用auto
using iter = vector<int>::iterator;//为便于书写,也可使用类型别名 (同typedef)
TreeNode
*
buildOneLevel
(
iter pre_begin
,
iter pre_end
,
iter in_begin
,
iter in_end
)
{
if
(
pre_begin
==
pre_end
||
in_begin
==
in_end
)
return
nullptr
;
//递归出口一(除结尾外还需要一个内部return,即两个return吧)
//先找根节点(
用前序遍历序列)
TreeNode
*
root
=
new TreeNode(*pre_begin);
//前序遍历序列首元素即为根结点
//在找左子树和右子树(用中序遍历序列) (具体只用求左子树序列长度就可以了)
vector
<
int
>::
iterator in_root_pos
=
find
(
in_begin
,
in_end
,
root
->
val
);
//先找到中序遍历序列中根节点的位置 (由于序列中不含重复元素,故可以用此方法)
int
left_length
=
in_root_pos
-
in_begin
;
//左子树序列长度
root
->
left
=
buildOneLevel
(
pre_begin
+
1
,
pre_begin
+
left_length
+
1
,
in_begin
,
in_root_pos
);
//左子树(
对于顺序容器的迭代器可以直接加某个常数,其他容器迭代器需用distance、next等函数)
root
->
right
=
buildOneLevel
(
pre_begin
+
left_length
+
1
,
pre_end
,
in_root_pos
+
1
,
in_end
);
//右子树
// !!注意end指向容器末尾(最后一个元素的下一个位置)
return
root
;
//递归出口二
}
};
106
.
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.
For example, given
inorder = [9,3,15,20,7]
postorder = [9,15,7,20,3]
Return the following binary tree:
3
/ \
9 20
/ \
15 7
/**
* 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
*
buildTree
(
vector
<
int
>&
inorder
,
vector
<
int
>&
postorder
)
{
return
build
(
postorder
.
begin
(),
postorder
.
end
(),
inorder
.
begin
(),
inorder
.
end
());
}
private
:
using
iter
=
vector
<
int
>::
iterator
;
//类型别名
TreeNode
*
build
(
iter post_begin
,
iter post_end
,
iter in_begin
,
iter in_end
)
{
if
(
post_begin
==
post_end
||
in_begin
==
in_end
)
return
nullptr
;
//先找
根结点
(后序遍历最一个元素)
TreeNode
*
root
=
new
TreeNode
(*(
post_end
-
1
));
//注意容器的end迭代器指向最后一个元素的下一个位置,而非最后一个元素!!
// cout<<root->val<<endl;
//再找左右子树(通过中序遍历,找到左右子树的分割点,求出左子树的长度)
vector
<
int
>::
iterator in_root_pos
=
find
(
in_begin
,
in_end
,
root
->
val
);
//同过迭代器将STL中容器与算法联系起来
int
left_length
=
in_root_pos
-
in_begin
;
//左子树
root
->
left
=
build
(
post_begin
,
post_begin
+
left_length
,
in_begin
,
in_root_pos
);
/
/右子树
root
->
right
=
build
(
post_begin
+
left_length
,
post_end
-
1
,
in_root_pos
+
1
,
in_end
);
return
root
;
}
};