LCR 175. 计算二叉树的深
某公司架构以二叉树形式记录,请返回该公司的层级数。
AC
int calculateDepth(struct TreeNode* root) {
if (root == NULL)
{
return 0;
}
else
{
return 1 + fmax(calculateDepth(root->left), calculateDepth(root->right));
}
}
代码思路
我这里直接使用的函数,在C语言中没有max函数,只有fmax函数,在头文件<math.h>中,C++中有max函数。
使用递归,当前节点是空就返回0,告诉上一层你已经是最后一层了,上一层就可以返回1,接着就开始逐次向上传递,传递的过程中,要看传递上来的值哪边更大,因为深度是看最大的一条路径,只需要传递最大的就可以,所以直接用函数比较出来然后传递就可以。
965. 单值二叉树
如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。
只有给定的树是单值二叉树时,才返回 true;否则返回 false。
AC
bool isUnivalTree(struct TreeNode* root) {
if(root == NULL)
{
return true;
}
if(root->left && root->left->val != root->val)
{
return false;
}
if(root->right && root->right->val != root->val)
{
return false;
}
return isUnivalTree(root->left) && isUnivalTree(root->right);
}
代码思路
遍历一遍所有节点,但是在遍历的过程中,进行当前节点和他的左子树与右子树结点的值的比较,前提是有左子树结点和右子树结点,如果说,有左子树也有右子树结点,就需要继续向下检查,如果值不同就返回false,遍历到最底下为空返回true开始返回,返回的时候用逻辑与,这样只要有一个false最后就不是单值,反之是单值。
101. 对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。
AC
bool _isSymmetric(struct TreeNode* root1,struct TreeNode* root2) {
// 都为空
if(root1 == NULL && root2 == NULL)
{
return true;
}
// 其中一个不为空
if(root1 == NULL || root2 == NULL)
{
return false;
}
// 都不为空但值不同
if(root1->val != root2->val )
{
return false;
}
return _isSymmetric(root1->left, root2->right)
&& _isSymmetric(root1->right, root2->left);
}
bool isSymmetric(struct TreeNode* root) {
return _isSymmetric(root->left, root->right);
}
代码思路
检查是否对称,那就是检查子树的左子树和右子树是否对称,原函数传入root没办法递归,所以创建子函数传进去左右子树进行检查。检查对称首先检查当前节点是否相同,再检查,左子树的左子树和右子树的右子树,左子树的右子树和右子树的左子树是否相同,整体思路和检查是否是同一棵树相同,分为三种if,1.当前两颗子树均为空 2.其中一颗为空 3.都不为空但是值不同,这三种都不符合说明当前两个节点相同且还有子树,仍可以向下递归,调用递归函数。这道题要注意判断的时候,他是镜像的,是左右子树对称。
100. 相同的树
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
AC
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
// 都为空
if(p == NULL && q == NULL)
{
return true;
}
// 其中一个为空
if(p == NULL || q == NULL)
{
return false;
}
// 都不为空且不相等
if(p->val != q->val)
{
return false;
}
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
代码思路
整体逻辑:先比较根,不相等就返回false,相等就检查左子树和右子树
比较根的情况:都为空,则返回true;其中一个为空,左或右肯定还有子树,那肯定不一样,返回false;都不为空,但是不相等,返回false。如果以上都不是,那说明该节点相等且有子树,那就接着去检查他的子树,执行递归语句。
572. 另一棵树的子树
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
AC
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
// 都为空
if(p == NULL && q == NULL)
{
return true;
}
// 其中一个为空
if(p == NULL || q == NULL)
{
return false;
}
// 都不为空且不相等
if(p->val != q->val)
{
return false;
}
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
if(root == NULL)
return false;
if(root->val == subRoot->val)
{
if(isSameTree(root,subRoot))
{
return true;
}
}
return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}
代码思路
判断子树里是否包含另一棵树,本质还是检查两棵树是否相同,但是需要找到相同树部分的根节点,也就是要先遍历子树节点,找到与subroot->val
相同的值,找不到的话就直接返回false
,找到后检查是否相同,相同则返回true。但是这里要思考一个情况,当前根节点的值相同,子树不相同,但是子树与subroot根节点相同,如图,当遍历到第一个4的时候,442与412不同,这时候不能直接返回false
,因为他的左子树412与subroot相同,因此需要继续向下遍历并检测是否相同,因此在判断root的值是否相同后再以判断是否相同为条件,不相同继续向下遍历,直到检测到NULL。