题目描述如下:
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
Note:
Bonus points if you could solve it both recursively and iteratively.
个人思路:
注意到题目描述最后提到,使用迭代和递归的方法会有加分,那么我就决定使用递归来做这个题。首先思考这个题,判断一个二叉树是否为镜像,首先要结构上镜像,其次要数据上镜像,只要有一处不符合即可对此进行否定。这个时候我又想到了二叉树的遍历相关知识,我们比较常用的有先序遍历NLR,中序遍历LNR以及后续遍历LRN。
经过观察除去根节点之后的两个符合镜像要求的二叉树(后面我们分别称为1、2)之后,我们发现,当我们沿着1的左孩子节点向下遍历时,与我们沿着2的右孩子节点向下遍历所得到的新的子树仍旧满足镜像对称。反过来,如果我们沿着1的右孩子节点向下遍历时,与我们沿着2的左孩子节点向下遍历所得到的新的子树同样满足镜像对称。
通过上面的发现,我们可以开始着手解决问题了。对于两颗镜像对称的二叉树,我们可以通过改写递归遍历算法来对其进行判断是否合法。对于根节点的左子树,我们选择LNR的中序遍历,但是对于根节点的右子树,我们选择RNL的中序遍历来实现。只要在遍历时有一处出现不合法,即可中止遍历,返回false。
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
bool check(TreeNode* node1,TreeNode* node2){ //改写的遍历算法,同时可以遍历两棵树
if(!node1 && !node2) return true; //两个皆NULL符合直接返回true
else if(!node1 || !node2) return false; //一个NULL一个非NULL,结构上失衡,返回false
if(check(node1->left,node2->right)){ //左子树选择LNR遍历,右子树选择RNL遍历
if(node1->val != node2->val) return false; //结构合法的前提下判断数据是否合法
else return check(node1->right,node2->left);
}
else return false;
}
bool isSymmetric(TreeNode* root) {
if(!root) return true; //空树
else return check(root->left,root->right);//树非空,将树分左右两个子树去遍历
}