检查一个二叉树是否是镜像的
1.递归实现
毫无疑问,递归的实现比较容易,从根节点的左右孩子开始,先判断根的特殊情况,再进入递归,判断是在回溯的时候判断。
官方解法是把2个root当作第一次左右传入,这个想法很好,代码也好看
bool isSymmetric(TreeNode* root) {
if(root == nullptr){
return true;
}
if(root->left == nullptr && root->right == nullptr){
return true;
}
else if(root->left != nullptr && root->right != nullptr){
return is(root->left,root->right);
}
return false;
}
//
bool is(TreeNode *l,TreeNode *r){
if(l == nullptr && r == nullptr){
return true;
}
//这句是可以去掉的
/*if(l == nullptr || r == nullptr){
return false;
}*/
/*if(l != nullptr && r != nullptr && l->val == r->val){
return is(l->left,r->right) && is(l->right,r->left);
}*/
return l != nullptr && r != nullptr && l->val == r->val &&is(l->left,r->right) && is(l->right,r->left);
//return false;
}
2.非递归
非递归想到了栈,大概思路是用2个栈分别存入当前节点的左右,然后循环
2.1 2个栈,遇到的难题主要是在判断时,没有把情况考虑清楚,什么时候该continue,什么时候直接false,总是报错nullptr
//2个栈实现
bool isSymmetric(TreeNode* root) {
if(root == nullptr)
return true;
//判断根节点得左右孩子是否满足
if((root->left != nullptr && root->right == nullptr) || (root->left == nullptr && root->right != nullptr)){
return false;
}
//当左右孩子都存在
if(root->left != nullptr && root->right != nullptr){
stack<TreeNode*>s1;
stack<TreeNode*>s2;
//左右入栈,主要是为了第一次进while,应该可以优化
s1.push(root->left);
s2.push(root->right);
while(!s1.empty() && !s2.empty()){
TreeNode* l = s1.top();
TreeNode* r = s2.top();
//出栈
s1.pop();
s2.pop();
//判断节点值是否相等
if(l == nullptr && r == nullptr) continue;
if(l == nullptr || r == nullptr) return false;
if(l->val != r->val){
return false;
}
//放在这里会出错,不知道为什么
/*s1.pop();
s2.pop();*/
//这个问题困扰我很久,当当前节点的孩子与对应节点的孩子不满足情况(一个为空,一个不为空,一共四种情况),直接返回false
s2.push(r->left);
s2.push(r->right);
s1.push(l->right);
s1.push(l->left);
}
//如果最后,都出栈了,说明ok
}
return true;
}
2.2 1个栈
一个栈实现,代码实现更容易,主要是没想到这个思路,思路很重要
bool isSymmetric(TreeNode* root) {
if(root == nullptr)
return true;
stack<TreeNode*>s1;
s1.push(root->left);
s1.push(root->right);
while(!s1.empty()){
TreeNode*l = s1.top();
s1.pop();
TreeNode*r = s1.top();
s1.pop();
if(r == nullptr && l == nullptr){
continue;
}
if(r == nullptr || l == nullptr){
return false;
}
if(l->val != r->val)
return false;
s1.push(r->left);
s1.push(l->right);
s1.push(r->right);
s1.push(l->left);
}
return true;
}
总结一下,非递归用其他容器也可以,总体思路差不多。
总的思路就是前中后序的非递归的基础,这个题做了挺久,还是三序的代码不熟练,思路理的不太清楚