Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree [1,2,2,3,4,4,3]
is symmetric:
1 / \ 2 2 / \ / \ 3 4 4 3
But the following [1,2,2,null,3,null,3]
is not:
1 / \ 2 2 \ \ 3 3
题目分析:
1、根据题干要求这道题目需要我们判断一棵树是否为对称的;
2、首先这道题目不能简单的用BFS判断每层元素是否相同,因为即元素相同也不能保证位置上的对称;
3、虽然这道题目不能直接简单利用BFS,但是却仍然可以建立在BFS的队列实现基础上。基本原理为把对称树分为根节点、左子树和右子树。那么判断一棵树是否为对称树只需要判断左右子树是否对称即可,判断对称的原理只需要左右子树分别BFS,BFS过程中在每层放入子节点的过程中一个先左后右一个先右后左实现对称搜索,并判断对称结点的val是否相同。
4、根据具体的情况把给出的树分为三种情况:
1)树为空,返回true;
2)树有根节点,但没有子节点,即左右子树都为空,返回true;
3)树有根结点,但只有一个子节点,即左右子树只有一个存在,另一个为空,返回false;
4)树有根结点且存在左右子树,那么建立左右子树的BFS队列L和R分别进行对称的BFS即可,具体判断原则参考3中说明。
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
#include<queue>
class Solution {
public:
bool isSymmetric(TreeNode* root) {
queue<TreeNode*> L;
queue<TreeNode*> R;
if(root == NULL)
return true;
if(root->left == NULL && root->right == NULL)
return true;
else if(root->left == NULL || root->right == NULL)
return false;
else{
if(root->left->val != root->right->val)
return false;
L.push(root->left);
R.push(root->right);
while(!(L.empty() || R.empty())){
TreeNode* NL = L.front();
TreeNode* NR = R.front();
if(!(NL->left == NULL || NR->right == NULL))
if(NL->left->val == NR->right->val){
L.push(NL->left);
R.push(NR->right);
}
else return false;
else if(NL->left != NULL || NR->right != NULL)
return false;
if(!(NL->right == NULL || NR->left == NULL))
if(NL->right->val == NR->left->val){
L.push(NL->right);
R.push(NR->left);
}
else return false;
else if(NL->right != NULL || NR->left != NULL)
return false;
L.pop();
R.pop();
}
return true;
}
}
};
总结:
这道题目的难点除了如何构思对称搜索的算法外,很重要的一点就是要考虑到所有的特殊情况。因为题目的对称搜索的准备有很多条件,不仅是必须有根结点,而且必须存在左右子树的情况下才能开始,那么在不满足这个条件的几种基本情况就需要单独进行判断。当然在这道题目中由于LeetCode会给出错误样例所以可以根据错误样例来找出遗漏的特殊情况,但是如果没有此类辅助的话对于自己在编写代码时考虑的全面性就是一个巨大的挑战。