难度: 简答
题目:
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
解题
可以将整棵树拆分成左右两颗子树来验证对称性,左子树的左节点,等于右子树的右节点;反之亦然。需要同时记录左右两个子树的节点遍历。
递归
递归思路很明确,与二叉树先序遍历算法基本一直,将当前所指向的节点看作将要遍历子树的跟节点,很重要的一点是要同时遍历左右两个子树,不然无法比较。
/**
* 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 isSymmetricEx(TreeNode* pLeft,TreeNode* pRight)
{
if(pLeft == nullptr && pRight == nullptr)
return true;
if(pLeft == nullptr || pRight == nullptr)
return false;
// 要同时满足三个条件:
// 1、当前值相等
// 2、左子树的左节点与右子树右节点相等
// 3、左子树的右节点与右子树左节点相等
return pLeft->val == pRight->val &&
isSymmetricEx(pLeft->left,pRight->right) &&
isSymmetricEx(pLeft->right,pRight->left);
}
bool isSymmetric(TreeNode* root) {
return isSymmetricEx(root,root);
}
};
递归(参考官方解答,只做记录)
通过引入队列的方式递归实现,首先将整棵树分为两颗树,如下:
1 1
| |
2 2
/ \ / \
3 4 4 3
成对进行比较,将1看作两个节点,因此递归前,将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;
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 isSymmetric(TreeNode* root) {
return check(root, root);
}
};