LCR 145. 判断对称二叉树 36min[法1看答案]+35min[法2看答案]
题目
方法一:递归
我的:没思路
原因是一直盯着“对称”二字,没有具体思考“对称”对应到逻辑上是怎样的。看了答案后才知道,其实就是一种新的树的定义,就像是二叉树的定义,满树这样的定义一样。用这个数据结构(二叉树)模拟出这个树的定义即可。
【思考】看了路飞答案后受到的思考如下,想要定义一个递归的对称二叉树。
一个树是对称二叉树,则满足:
- 是空树
- 只有一个节点,则其left==right
- 不止一个节点,则判断左右子树是否相等,(这里有疑惑,觉得不太对)
写的代码如下:是错的
//错误
class Solution {
public:
bool checkSymmetricTree(TreeNode* root) {
if(root==NULL)
return true;
if(root->left==NULL&&root->right==NULL)
return true;
if(root->left&&root->right&&root->left->val==root->right->val)
return true;
else if((root->left&&root->right==NULL)||(root->left==NULL&&root->right)||(root->left&&root->right&&root->left->val!=root->right->val))
return false;
return checkSymmetricTree(root->left)&&checkSymmetricTree(root->right);
}
};
【错因】:要判断的是两个树是否对称,所以每次应该传入两个数根节点,判断是否是对称的,而不是像遍历树一样,这样是判断不出来的,我写的是判断同一个树根下的左右兄弟是否值是一样的,而不没有判断整个的树。
【理清思路后写的】:
class Solution {
public:
bool check(TreeNode* root1,TreeNode* root2)
{
if(root1==NULL&&root2==NULL)
return true;
if(root1==NULL||root2==NULL)//前面已经判断了,所以这里要么是两个不为空,要么一空一不空
return false;
if(root1->val!=root2->val)
return false;
return check(root1->left,root2->right)&&check(root1->right,root2->left);
}
bool checkSymmetricTree(TreeNode* root) {
if(root==NULL)
return true;
return check(root->left,root->right);
}
};
方法二:迭代
用queue,但是我还是不会去判断情况
写的如下:错的,写不下去了
class Solution {
public:
bool check(TreeNode* u,TreeNode*v)
{
queue<TreeNode*> q;
q.push(u);
q.push(v);
while(!q.empty())
{
if(u->val!=v->val)
return false;
if((u->left==NULL&&v->right)||(u->left&&v->right==NULL))
return false;
if((u->right==NULL&&v->left)||(u->right&&v->left==NULL))
return false;
if(u)
}
}
bool checkSymmetricTree(TreeNode* root) {
if(root==NULL)
return true;
check(root,root);
}
}
};
答案:
class Solution {
public:
bool check(TreeNode* u,TreeNode*v)
{
queue<TreeNode*> q;
q.push(u); q.push(v);
while(!q.empty())
{
u=q.front(); q.pop();
v=q.front(); q.pop();
if(!u&&!v) //都是空,则continue,这里是我不会处理的
continue;
if((!u||!v)||(u->val!=v->val))
return false;
q.push(u->left); //不用管左右子树是否为空,全部入队列,而我一直在判断,造成了复杂性
q.push(v->right);
q.push(u->right);
q.push(v->left);
}
return true;
}
bool checkSymmetricTree(TreeNode* root) {
if(root==NULL)
return true;
return check(root,root);
}
};
【反思】简化判断,空的也可以入队列,不需要检查左右子树是否为空。
LCR 144. 翻转二叉树
题目
这个题目和上面的有点相似,刚开始按照上面的思路去写,结果不对,因为反转和对称不一样,对称是轴对称,而反转是左右子树反转,小范围的,镜像是大范围轴对称的,因此这个的递归不需要传入两个参数,只需要dfs遍历即可。
错的:
class Solution {
public:
void reverseTree(TreeNode* u,TreeNode*v)
{
if(!u&&!v)
swap(u->val,v->val);
if(u->left&&v->right) reverseTree(u->left,v->right);
if(u->right&&v->left) reverseTree(u->right,v->left);
}
TreeNode* mirrorTree(TreeNode* root) {
if(root==NULL) return NULL;
reverseTree(root->left,root->right);
return root;
}
};
正确的:
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
if(root==NULL) return NULL;
TreeNode* t=root->left;
root->left=mirrorTree(root->right);
root->right=mirrorTree(t);
return root;
}
};
LCR 175. 计算二叉树的深度
题目
计算二叉树的高度
class Solution {
public:
int calculateDepth(TreeNode* root) {
if(root==NULL) return 0;
if(root->left==NULL&&root->right==NULL) return 1;
int lh=calculateDepth(root->left);
int rh=calculateDepth(root->right);
if(lh>rh) return lh+1;
return rh+1;
}
};