101. 对称二叉树
力扣题目链接
给定一个二叉树,检查它是否是镜像对称的。
思路
镜像对称必要的条件就是根节点的左右子树互相对称
- 左子树的左孩子 = 右子树的右孩子
- 左子树的右孩子 = 右子树的左孩子
递归
使用递归前要确定递归的顺序,是前序、后序还是中序。
这道题用后序遍历比较好。根据上面的比较逻辑,我们可以知道,其实要比较的树就只有根节点的左右两个子树。
我们不妨将之看成两棵树进行比较。
如果是后序遍历,左树的则是先比较外侧再比较内侧,而右树则是先比较外侧再内侧,符合我们的比较顺序。
确定号递归顺序后,我们要确定终止条件
- 如果左右树均为空,则返回true
- 如果左右树只有一个为空或者值不相等,返回false
- 如果左右树存在且值相等,进行单层遍历
单层遍历的逻辑上面已经说过了,先外侧再内侧,因此代码有如下:
class Solution {
public:
bool cpy(TreeNode* left, TreeNode* right){
if(left == nullptr && right == nullptr)return true;
else if(left == nullptr || right == nullptr)return false;
else if(left->val != right->val)return false;
// 左右子节点存在且值相同
bool outside = cpy(left->left,right->right);
bool inside = cpy(left->right,right->left);
return outside&&inside;
}
bool isSymmetric(TreeNode* root) {
if(root == nullptr)return true;
return cpy(root->left,root->right);
}
};
迭代
迭代的思路则简单得多,我们使用队列,将左右子树的结点一对对放进去,再一对对拿出来比较即可。
代码如下:
class Solution {
public:
bool isSymmetric(TreeNode* root) {
queue<TreeNode*> qu;
if(root == nullptr)return false;
qu.push(root->left);
qu.push(root->right);
while(!qu.empty()){
TreeNode* leftNode = qu.front();qu.pop();
TreeNode* rightNode = qu.front();qu.pop();
if(leftNode == nullptr && rightNode == nullptr)continue;
if(!leftNode || !rightNode || leftNode->val != rightNode->val)
return false;
qu.push(leftNode->left);
qu.push(rightNode->right);
qu.push(leftNode->right);
qu.push(rightNode->left);
}
return true;
}
};
qu.push(rightNode->left);
}
return true;
}
};