题目描述
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [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
解决方案
方法一:递归
如果一个树的左子树与右子树镜像对称,那么这个树是对称的。
因此,该问题可以转化为:两个树在什么情况下互为镜像?
如果同时满足下面的条件,两个树互为镜像:
1.它们的两个根结点具有相同的值。
2.每个树的右子树都与另一个树的左子树镜像对称。
就像人站在镜子前审视自己那样。镜中的反射与现实中的人具有相同的头部,但反射的右臂对应于人的左臂,反之亦然。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
return isMirror(root,root);
}
bool isMirror(TreeNode *p1,TreeNode *p2){
if(!p1 && !p2)
{
return true;
}
if(!p1 || !p2)
{
return false;
}
if(p1->val == p2->val)
return isMirror(p1->left,p2->right)&&isMirror(p1->right,p2->left);
return false;
}
};
方法二:迭代
除了递归的方法外,我们也可以利用队列进行迭代。队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像。最初,队列中包含的是 root
以及 root
。该算法的工作原理类似于 BFS
,但存在一些关键差异。每次提取两个结点并比较它们的值。然后,将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25class Solution{
public:
bool isSymmetric(TreeNode* root){
if(!root) return true;
queue<TreeNode *> p1,p2;
p1.push(root->left);
p2.push(root->right);
while(!p1.empty() && !p2.empty()){
TreeNode* node1 = p1.front();
TreeNode* node2 = p2.front();
p1.pop();
p2.pop();
if((node1 && !node2)|| (!node1 && node2)) return false;
if(node1){
if(node1->val != node2->val) return false;
p1.push(node1->left);
p1.push(node1->right);
p2.push(node2->right);
p2.push(node2->left);
}
}
return true;
}
};