题目描述
给你一个二叉树的根节点 root
, 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3] 输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3] 输出:false
解题方法
一、递归法
从递归的角度判断二叉树是否对称,也就是要判断左右子树是否对称,首先判断是否存在,然后判断是否相等。
由于只传入根节点,而又需要判断左右子树因此新建一个函数,传入左右子树,返回是否对称。递归时若是左右子树都不存在说明到达叶子节点直接返回true,若左右有一方存在则不对称返回false,若都存在但值不相等则返回false。最后进行递归左子树的左孩子和右子树的右孩子,以及左子树的右孩子和右子树的左孩子是否相等。
代码实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
//空子树是对称的
if(!root){
return true;
}
//判断左右子树是否对称
return childIsSymmetrick(root->left,root->right);
}
bool childIsSymmetrick(TreeNode* l,TreeNode* r){
//左右子树为空为叶子节点
if(!l && !r){
return true;
}
//若左右子树不全为空或者都存在但值不同则不对称返回false
if(!l || !r || l->val != r->val){
return false;
}
//分别判断左子树的左孩子和右子树的右孩子,以及左子树的右孩子和右子树的左孩子的节点是否相同
return childIsSymmetrick(l->left,r->right) && childIsSymmetrick(l->right,r->left);
}
};
二、层次遍历
用队列存储节点,首先,将非空子树的左右子树入队。其次,循环出队入队进行遍历,每次将两个节点出队,开始比较,若都为空,则进入下一循环继续出队;若一方为空一方不为空则返回false;若都存在但二者的值不相等,则也返回false。之后,将下一层的节点以轴对称的方式入队,即左孩子的左子树入队,然后右孩子的右子树入队,再然后左孩子的右子树入队,最后将右孩子的左子树入队。若最终运行到循环结束,则说明该二叉树是对称的。
代码实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
//空子树是对称的
if(!root){
return true;
}
queue<TreeNode*> qu;
//左右子树入队
qu.push(root->left);
qu.push(root->right);
//循环遍历左右子树
while(!qu.empty()){
TreeNode* left = qu.front();
qu.pop();
TreeNode* right = qu.front();
qu.pop();
//空节点则继续往后遍历其他对应节点
if(!left&&!right){
continue;
}
//左右子树结构不对称
if(!left&&right || left && !right){
return false;
}
//比较左右节点值是否相等
if(left->val != right->val){
return false;
}
qu.push(left->left);
qu.push(right->right);
qu.push(left->right);
qu.push(right->left);
}
return true;
}
};
总结
写递归时,终止条件要整理清楚,否则会出现漏判导致出错。
灵活应用栈队列结构,根据题目可能需要连续多次的入队出队的情况。