树
树的遍历
前序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void preorder(TreeNode* root,vector<int> &res)
{
if(root==nullptr)
return;
res.push_back(root->val);
preorder(root->left,res);
preorder(root->right,res);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
preorder(root,res);
return res;
}
};
中序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void inorder(TreeNode* root,vector<int>& res)
{
if(root==nullptr)
return;
inorder(root->left,res);
res.push_back(root->val);
inorder(root->right,res);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
inorder(root,res);
return res;
}
};
后序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void postOrder(TreeNode* root,vector<int>& res)
{
if(root==nullptr)
return;
postOrder(root->left,res);
postOrder(root->right,res);
res.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> arr;
postOrder(root,arr);
return arr;
}
};
层序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(root==nullptr)
return res;
queue<TreeNode*> qu;
qu.push(root);
int level=0;
while(!qu.empty())
{
level++;
vector<int> levevRes;
//每一层的个数等于当前的队列长度
int levelSize=qu.size();
for(int i=0;i<levelSize;i++)
{
TreeNode* cur=qu.front();
levevRes.push_back(qu.front()->val);
qu.pop();
if(cur->left)
{
qu.push(cur->left);
}
if(cur->right)
{
qu.push(cur->right);
}
}
res.push_back(levevRes);
}
return level;
}
};
运用递归解决问题
二叉树树的深度
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
vector<vector<int>> res;
if(root==nullptr)
return 0;
queue<TreeNode*> qu;
qu.push(root);
int level=0;
while(!qu.empty())
{
level++;
vector<int> levevRes;
//每一层的个数等于当前的队列长度
int levelSize=qu.size();
for(int i=0;i<levelSize;i++)
{
TreeNode* cur=qu.front();
levevRes.push_back(qu.front()->val);
qu.pop();
if(cur->left)
{
qu.push(cur->left);
}
if(cur->right)
{
qu.push(cur->right);
}
}
res.push_back(levevRes);
}
return level;
}
};
对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//如果一棵树的前序遍历和后续遍历相等那就是镜像对称
bool isSymmetric(TreeNode* root) {
return check(root,root);
}
bool check(TreeNode*left,TreeNode*right)
{
if(left==nullptr&&right==nullptr)
{
return true;
}
if(left==nullptr||right==nullptr)
{
return false;
}
return (left->val==right->val)&&check(left->left,right->right)&&check(left->right,right->left);
}
};
路径总和
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
//如果根节点为空返回false
if(root==nullptr)
return false;
//如果左右都为空此时的总和就是到叶子结点的路径和
if(root->left==nullptr&&root->right==nullptr)
return root->val==targetSum;
return hasPathSum(root->left,targetSum-root->val)||hasPathSum(root->right,targetSum-root->val);
}
};
总结
从前序遍历与后序遍历构造二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size()==0)
return nullptr;
return dfs(inorder,postorder,0,inorder.size()-1,0,postorder.size()-1);
}
//中序遍历的根节点在中间
TreeNode* dfs(vector<int>& inorder, vector<int>& postorder,int inStart,int inEnd,int postStart,int postEnd){
if(inStart>inEnd)
return nullptr;
//树的根节点的后序遍历的最后一个结点
TreeNode* root=new TreeNode(postorder[postEnd]);
//TreeNode* root=new TreeNode(20);
//如果中序遍历的头和尾都相等,则说明已经访问完,返回这棵树
if(inStart==inEnd)
return root;
//以根节点的值为中心,左右两边分别是根节点的子树的结点
int mid=0;
//从当前中序遍历的数组的第一个点开始搜索,直到找到根节点
while((root->val)!=inorder[inStart+mid])mid++;
//左子树是根节点中序遍历左边那部分
root->left= dfs(inorder,postorder,inStart,inStart+mid-1,postStart,postStart+mid-1);
//右子树是根节点中序遍历右边那部分
root->right=dfs(inorder,postorder,inStart+mid+1,inEnd,postStart+mid,postEnd-1);
return root;
}
};
从前序遍历与中序遍历构造二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
//如果前序遍历或者中序遍历长度为0或者长度不相等,树不存在
int prelen=preorder.size();
int inlen=inorder.size();
if(prelen==0||inlen==0||prelen!=inlen)
return nullptr;
return dfs(preorder,inorder,0,prelen-1,0,inlen-1);
}
TreeNode* dfs(vector<int>& preorder, vector<int>& inorder,int preStart,int preEnd,int inStart,int inEnd)
{
//如果坐标越界返回空值
if(preStart>preEnd)
return nullptr;
//根节点是先序遍历的第一个结点
TreeNode* root=new TreeNode(preorder[preStart]) ;
//如果两者相等,说明遍历完了这棵树,返回根节点
if(preStart==preEnd)
return root;
//找到中序遍历中和根节点相同的结点的相对坐标,mid-1其实就是左子树的结点个数
int mid=0;
while(root->val!=inorder[inStart+mid])mid++;
//中序遍历中根节点两边分别为左右子树
root->left=dfs(preorder,inorder,preStart+1,preStart+mid,inStart,inStart+mid-1);
root->right=dfs(preorder,inorder,preStart+mid+1,preEnd,inStart+mid+1,inStart);
return root;
}
};
填充每个节点的下一个右侧节点指针
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
Node* connect(Node* root) {
//如果根节点为空返回root
if(root==nullptr)
return nullptr;
//把根节点的左右结点连接
dfs(root->left,root->right);
return root;
}
void dfs(Node* left,Node* right)
{
//如果左右结点有空值,返回nullptr
if(left==nullptr||right==nullptr)
return;
//把左右结点连起来
left->next=right;
dfs(left->left,left->right);
dfs(left->right,right->left);
dfs(right->left,right->right);
}
};
填充每个节点的下一个右侧节点指针 II
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
Node* connect(Node* root) {
if(root==nullptr)
return nullptr;
if(root->left!=nullptr)
{
//如果左右孩子不为空,左孩子指向右孩子
if(root->right!=nullptr)
{
root->left->next=root->right;
}
//左孩子不为空,右孩子为空,左孩子指向父节点的next结点的最左边那个孩子
else{
root->left->next=getFirstChild(root->next);
}
}
//右孩子不为空那就让右孩子连接
if(root->right!=nullptr)
{
root->right->next=getFirstChild(root->next);
}
//再连接左子树和右子树
//要先连接右子树,才能确保找到next结点
connect(root->right);
connect(root->left);
return root;
}
//用于获取当前结点的最左边的孩子结点
Node* getFirstChild(Node* root){
if(root==nullptr)
return nullptr;
//左孩子不为空,返回左孩子
if(root->left!=nullptr)
return root->left;
//左孩子不为空,右孩子为空,返回右孩子
if(root->right!=nullptr)
return root->right;
//否则再搜索下一个结点
return getFirstChild(root->next);
}
};
二叉树的最近公共祖先
/**
* 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* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//如果root是空或者两个节点有一个结点为根节点,那就直接返回根节点
//因为此时根节点就是最近公共祖先
if(root==nullptr||root==p||root==q)
return root;
//否则就找左右子树里pq的最近公共祖先
TreeNode*left=lowestCommonAncestor(root->left,p,q);
TreeNode*right=lowestCommonAncestor(root->right,p,q);
//如果左孩子找不到pq的话说明在右孩子上
if(left==nullptr)
return right;
//如果右孩子找不到pq那就说明在左孩子上
if(right==nullptr)
return left;
//如果左右孩子都找到了说明一个在左孩子一个在右孩子上。返回当前结点即可
return root;
}
};
二叉树的序列化和反序列化
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
TreeNode* node;
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
node=root;
return "";
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
return node;
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
-
写了一个晚上没写出来,看到题解我惊呆了
-
我思路是把原来结点转化为前序遍历和中序遍历,然后根据中序遍历和前序遍历来转化成原来的数,但是一直有问题,明天再看看问题在哪
-
还看到用层序遍历存树然后再还原的,这个也好牛呀