题目:Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).For example, this binary tree is symmetric:题目源自于Leetcode。
1
/ \
2 2
/ \ / \
3 4 4 3
之前错误的思路:先中序遍历,在遍历过程中生成整个树的中序序列,然后判断这个序列是否是回文序列。这个错误在于“二叉树对称”是“中序序列是回文”的充分不必要条件。
//错误方案
class Solution {
public:
bool isSymmetric(TreeNode *root) {
if(root == NULL)
return true;
vector<int> v;
fun(root, v);
int n = v.size();
if(n%2==0) //必定是奇数个元素才能对称
return false;
int i;
for(i=1;i<=n/2;i++) //判断是否是回文
{
if(v[n/2+i] != v[n/2-i])
return false;
}
return true;
}
void fun(TreeNode *root, vector<int> &v)
{
if(root != NULL)
{
fun(root->left, v);
v.push_back(root->val);
fun(root->right, v);
}
}
};
思路1:递归思想,对称二叉树的左右两个子树一定是镜面对称的。对于镜面对称判断其左右结点的孩子是否是镜面的,递归进行下去。
class Solution {
public:
bool isSymmetric(TreeNode *root) {
if(root == NULL)
return true;
return isSym(root->left, root->right);
}
bool isSym(TreeNode *p1, TreeNode *p2)
{
if(p1 == NULL && p2 == NULL)
return true;
else if(p1 == NULL || p2 == NULL)
return false;
else if(p1->val == p2->val)
{
return isSym(p1->left, p2->right) && isSym(p1->right, p2->left);
}
else
return false;
}
};
思路2:先将原二叉树镜面对称过来变成另一个二叉树,然后判断两个二叉树是否是完全相同的。
class Solution {
public:
bool isSymmetric(TreeNode *root) {
TreeNode *mi = mirror(root);
return isEqual(mi, root);
}
TreeNode* mirror(TreeNode *root) //生成镜像化的二叉树
{
if(root == NULL)
return NULL;
TreeNode *nroot = new TreeNode(root->val);
nroot->left = mirror(root->right);
nroot->right = mirror(root->left);
return nroot;
}
bool isEqual(TreeNode *p1, TreeNode *p2) //判断两个二叉树是否完全相等
{
if(p1 == NULL && p2 == NULL)
return true;
else if(p1 == NULL || p2 == NULL)
return false;
if(p1->val == p2->val)
return isEqual(p1->left, p2->left) && isEqual(p1->right, p2->right);
else
return false;
}
};
思路3:层序遍历。层序遍历过程中不漏过任何一个空的孩子,直到最底层全部为空节点才结束遍历。每一层结束时判断一次该层的结点是否是回文。
该方法的时间复杂度并不高,可是我的实现却超时了。
class Solution {
public:
bool isSymmetric(TreeNode *root) {
queue<TreeNode *> q;
vector<int> level;
q.push(root);
TreeNode *enode = new TreeNode(-1);//每一层结束的标记
q.push(enode);
int count = 0;//记录是否到达全部为空节点的最底层
while(!q.empty())
{
TreeNode* tmp = q.front();
q.pop();
if(tmp == enode)
{
if(count == 0)
return true;
if(!isPalin(level))
return false;
level.clear();
count = 0;
if(!q.empty())
{
q.push(enode);
continue;
}
else
return true;
}
else if(tmp == NULL)
{
level.push_back(-1);
q.push(NULL);
q.push(NULL);
}
else
{
q.push(tmp->left);
q.push(tmp->right);
level.push_back(tmp->val);
count++;
}
}
}
bool isPalin(vector<int> &level)
{
int left = 0, right = level.size()-1;
while(left < right)
{
if(level[left++] != level[right--])
return false;
}
return true;
}
};