采用递归和迭代两种方法:
(1)递归:
在一开始做的时候,试图用二叉树的中序遍历来做。因为我发现对于对称的二叉树,中序遍历的结果也是对称的。所以以为,构建一个vector,然后中序遍历一遍,然后对这个vector,看是否对称,即可得到是否是对称二叉树。但是,运行时一个反例,让我明白这个简单粗暴的方法是不行的。比如下面这个例子,【1,2,3,3,null,2,null】这棵非对称二叉树的中序遍历结果为3,2,1,2,3
看似是对称的,但是其实这不是一棵对称的树。
所以,该方法不行。
https://leetcode-cn.com/problems/symmetric-tree/description/ 可以考虑采用上述的做法,即dfs中传入两个节点指针,分别往两个方向走。这样的递归非常的灵活,感觉又收获了新技能。
注意,leetcode第100题也是采用了传入了双指针,但是100题比较明显是要传入双指针,因为那是两棵树。
(2)迭代:这种方法从形式上类似我们递归的思路,即也是排查一个节点的左子树和另一个节点的右子树,以及一个节点的右子树和另一个节点的左子树,使用一个pair的变量存储,并压入到队列里。然后在弹出时进行结构(判空)和值(判值)的判断。这题AC的代码是我自己写的,但是思路是借鉴的b站视频的,他是用100题讲得迭代方法。可以回头再看一遍。
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root==NULL) return true;
queue<pair<TreeNode*,TreeNode*> > q;
q.push(make_pair(root,root));
while(!q.empty())
{
pair<TreeNode*,TreeNode*> temp=q.front();
q.pop();
// if(temp.first==temp.second&&temp.first!=NULL)
if((temp.first==NULL&&temp.second!=NULL)||(temp.first!=NULL&&temp.second==NULL))
{
return false;
}
if(temp.first!=NULL&&temp.second!=NULL)
{
if(temp.first->val!=temp.second->val)
{
return false;
}
if(temp.first->left!=NULL&&temp.second->right!=NULL)
{
q.push(make_pair(temp.first->left,temp.second->right));
}else if(temp.first->left==NULL&&temp.second->right==NULL)
{
q.push(make_pair(temp.first->left,temp.second->right));
}else return false;
if(temp.first->right!=NULL&&temp.second->left!=NULL)
{
q.push(make_pair(temp.first->right,temp.second->left));
}else if(temp.first->right==NULL&&temp.second->left==NULL)
{
q.push(make_pair(temp.first->right,temp.second->left));
}else return false;
}
}
return true;
}
};
(3)还有一种比较传统的方法,即按照对称的原始定义:如果一棵树的镜像和它是同样的,则称为是对称的。
注意,这样做的时候,需要提前拷贝出一个树的镜像,否则会破坏原来树的结构。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
///如果用题目给出的做法,则先拷贝一份,然后利用拷贝的那份再去输出镜像
class Solution {
public:
TreeNode* copyRoot(TreeNode* pRoot)
{
if(pRoot==NULL) return NULL;
TreeNode* root=new TreeNode(pRoot->val);
root->left=copyRoot(pRoot->left);
root->right=copyRoot(pRoot->right);
return root;
}
void jingxiang(TreeNode* root)
{
if(root==NULL) return;
jingxiang(root->left);
jingxiang(root->right);
swap(root->left,root->right);
}
bool dfs(TreeNode* p1,TreeNode* p2)
{
if(p1==NULL&&p2==NULL) return true;
if( (p1!=NULL&&p2!=NULL) && (p1->val==p2->val)) //这里的非空判断一定要有,因为只有保持非空,才能用下面的左右子树
{
return dfs(p1->left,p2->left) && dfs(p1->right,p2->right);
}
else return false;
}
bool isSymmetrical(TreeNode* pRoot)
{
TreeNode* cRoot=copyRoot(pRoot);
jingxiang(cRoot);
return dfs(pRoot,cRoot);
}
};