题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
分析:
还是画图分析,先画以下两幅图进行分析和讨论:
显然,两颗数结构上是对称的,但是数字上第二幅不是,所以只要是第一幅图这种情况就是对称的,我们来分析怎么用代码思想表述它。
提到二叉树,想到的就是三种不同二叉树的遍历方法,即前序遍历、中序遍历和后序遍历。在这三种遍历算法中,都是先遍历左子结点在遍历右子结点。评定是否为一颗对称树,最好想到的就是前序遍历,如果我们在定义一种类似于前序遍历的遍历方法:即先遍历父结点,再遍历右子结点,最后遍历左子结点。以上图为例:第一幅图中前序遍历为8657675,按新定义遍历为8657675,这两个序列是一样的。而第二幅图中前序遍历为8657975,按新定义遍历为8957675,这两个序列是有差别的。所以以上方法看似是有效的。
但是按照上述思路,下面这一情况就不满足了,如图:
这样的情况怎么解决呢?其实我们只要在遍历的时候把遇到的null指针也考虑进来就好了,就拿这幅图来说,前序遍历为[8 8 8 null null 8 null null 8 8 null null null],新定义遍历为[8 8null 8 null null 8 8 null null 8 null null],两个序列不一样,所以问题也得到了解决。
总结起来,可以通过比较二叉树的前序遍历序列和新定义类似前序遍历序列来判断二叉树是不是对称的,加入对null指针的考虑。如果两个序列是一样的,那么二叉树就是对称的。所以按此思路编写代码如下:
class Solution {
public:
//对称二叉树pRoot的镜像仍是pRoot,将根的左右子树进行比较是否对称。
bool isSymmetrical(TreeNode* pRoot)
{
return isSymmetrical(pRoot,pRoot);
}
///判断pRoot1和pRoot2是否对称。模拟pRoot2是pRoot1的镜像。
bool isSymmetrical(TreeNode* pRoot1,TreeNode* pRoot2)
{
if(pRoot1==nullptr&&pRoot2==nullptr)
return true;
if(pRoot1==nullptr)
return false;
if(pRoot2==nullptr)
return false;
if(pRoot1->val!=pRoot2->val)
return false;
return isSymmetrical(pRoot1->left,pRoot2->right)&&isSymmetrical(pRoot1->right,pRoot2->left);
}
};