【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;
}
};