1,求深度:
递归思想,一个点的深度 = 子树最大深度+1
【本质是DFS后序遍历】
class Solution {
public:
int maxDepth(TreeNode* root)
{
if(root == NULL)
return 0;
else
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
2,求是不是平衡二叉数
跟上一个相关,其实平衡二叉树就是求两个子树的深度差是否大于2
class Solution {
public:
int getdepth(TreeNode* root)
{
if(root == NULL)
return 0;
return max(getdepth(root -> left),getdepth(root -> right)) + 1;
}
bool isBalanced(TreeNode* root)
{
if(root == NULL)
return true;
return abs(getdepth(root -> right) - getdepth(root -> left)) < 2 && isBalanced(root -> left) && isBalanced(root->right);
}
};
3,重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例:
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
得出二叉树:
其实这个原理非常之简单,就是前中后序遍历的
前:根—>左节点—>右节点
中:左节点—>根—>右节点
后:左节点—>右节点—>根
递归的分析,前序的第一个就是根节点,根节点在中序出现的位置分割了左子树和右子树。
但是写起来很麻烦很麻烦很麻烦,我的代码也是copy大佬的
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
return temp(preorder.begin(),preorder.end(),inorder.begin(),inorder.end());
}
TreeNode* temp(vector<int>::iterator prebegin,vector<int>::iterator prend,vector<int>::iterator inbegin,vector<int>::iterator inend)
{
if(inbegin == inend)
return NULL;
TreeNode* node = new TreeNode(*prebegin);
auto root = find(inbegin,inend,*prebegin);
node -> left = temp(prebegin+1,prebegin+1+(root-inbegin),inbegin,root);
node -> right = temp(prebegin+1+(root-inbegin),prend,root+1,inend);
return node;
}
};
4,二叉树的层序遍历(BFS)
非递归实现嗷,用队列
class Solution {
public:
vector<int> levelOrder(TreeNode* root)
{
queue<TreeNode*> q;
vector<int> result;
if(root == NULL)
return result;
q.push(root);
while(!q.empty())
{
TreeNode* temp = q.front();
q.pop();
if(temp ->left)
q.push(temp->left);
if(temp -> right)
q.push(temp->right);
result.push_back(temp->val);
}
return result;
}
};
5,寻找最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
方法:
用了递归——其实这题挺难想明白的,我想了好久
如果是用递归,那我们需要先考虑普通情况,再考虑边界情况
普通情况:
如果左子树返回了值,而右子树没有,则说明此左子树的结点就是所求——反之亦然
如果左子树和右子树同时返回了,则返回这个结点本身
递归的分析,知道折腾到底又折腾上来
直接上代码吧,这题真解释不清楚
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
{
if(root == NULL)
return NULL;
if(root == p || root == q)
return root;
TreeNode* left = lowestCommonAncestor(root->left,p,q);
TreeNode* right = lowestCommonAncestor(root->right,p,q);
if(left == NULL)
return right;
if(right == NULL)
return left;
if(left && right)
return root;
return NULL;
}
};
6,对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
用递归做的!
这个好理解!看源码就行!
class Solution {
public:
bool compare(TreeNode* left,TreeNode* right)
{
if(left == NULL && right != NULL)
return false;
if(right == NULL && left != NULL)
return false;
if(left == NULL && right == NULL)
return true;
if(left->val != right -> val )
return false;
else
return compare(left->left,right->right) && compare(left->right,right->left);
}
bool isSymmetric(TreeNode* root)
{
if(root == NULL)
return true;
return compare(root->left,root->right);
}
};
其实迭代也可以做的——原理跟层序遍历差不多,运用队列比较每一层是否相同
但是不能直接比(我第一次就是每一层全扫进去然后看是否对称),如果这样的话,不能确定左右位置。