1. 题目描述
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
2. 样例
For example, this binary tree [1,2,2,3,4,4,3] is symmetric:
But the following [1,2,2,null,3,null,3] is not:
3. 分析
题目的意思是:给了一个二叉树的根节点,让我们判断这棵树是否是对称的,对称的意思是关于它的中心左右对称。
很明显,根据我的分析:树的对称是有两个条件的:
- 对应层次,左右节点的结构是对称的,即这一层左右节点数目是对称的:而且该层左面有N,M个左右孩子,右面就需要有对应的N,M个右左孩子。如上文的第一个例子是符合的,而上文第二个例子就是因为第二层左边有一个右孩子,而右边有一个右孩子,所以不对称。
- 对应节点数值:每一层只有结构对称还是不够,对应节点的数值也必须相同。
分析之后,我原来的想法是:利用层次遍历,遍历树的每一层,用一个栈stack来进行不断入栈出栈操作,从而进行匹配。但是这个思路被否决了,因为这个只能满足第二个数值匹配的要求,而无法满足结构对称的要求,例子2就可以进行反驳。
因此,我设计的算法是利用递归,分而治之:从根节点开始,不断判断每一层对应两个位置的节点情况,所谓的对应位置就是在该层成对称位置分布的节点:
- 如果一个为NULL,一个不为NULL:说明该层结构不对称,即不满足要求1,直接false
- 如果均为NULL,则true
- 如果均不为NULL,则判断节点存储数值:如果不同,则不满足要求2,直接false;如果相同,则继续查找该两个节点下的左右和右左孩子
如下图所示:
提交后,结果如下:
4. 源码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool comTwoNode(TreeNode*leftNode, TreeNode*rightNode) {
if (leftNode != NULL && rightNode != NULL) {
if (leftNode->val != rightNode->val) {
return false;
}
}
else if (leftNode != NULL || rightNode != NULL) {
return false;
}
else {
return true;
}
return comTwoNode(leftNode->left, rightNode->right)&&comTwoNode(leftNode->right, rightNode->left);
}
bool isSymmetric(TreeNode* root) {
if (root == NULL) {
return true;
}
return comTwoNode(root->left, root->right);
}
};
5. 心得
最近做BFS的题,一上来的思路就被非递归的层次遍历限制住了,稍加思考就能得到递归的清晰简单的算法。