Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree is symmetric:
1 / \ 2 2 / \ / \ 3 4 4 3
But the following is not:
1 / \ 2 2 \ \ 3 3
Note:
Bonus points if you could solve it both recursively and iteratively.
题目解析:
判断一棵树是否为左右镜像对称的树。如果能用递归和非递归两种实现更好。
方案一:递归方法
设一个函数,递归的时候,传入p的左子树和传入q的右子树递归,再传入p的右子树和q的左子树递归。然后判断返回值是否都为真。
一开始不一定能想到这种方法,多画图判断。
class Solution {
public:
bool isSymmetric(TreeNode *root) {
if(root == NULL)
return true;
return CompareTree(root->left,root->right);
}
bool CompareTree(TreeNode *p,TreeNode *q){
if(p == NULL && q == NULL)
return true;
if((p == NULL && q != NULL) || (p != NULL && q == NULL))
return false;
if(p->val != q->val)
return false;
return CompareTree(p->left,q->right) && CompareTree(p->right,q->left);
}
};
方案二:非递归方法
非递归的实现就要借助栈或者队列。栈的话,本身就是一种递归的方法。这里看看用队列能否实现。
一开始想的设置一个队列,入队列的时候,按照p->left,q->right,p->right,q->left的顺序。然后取出队列,要一次取出两个。当然碰到叶节点的时候的空指针要额外处理一下。同时防止左右子树不等长的情况。有点繁琐,不过还是能实现的。
我们也可以设置两个队列,根的左子树一个,根的右子树一个。队列中放入指向结点的指针。一边出队列,一边将该结点的左右孩子入队列。当然也要遵循左右交替的入队列。
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode *root) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if(root==NULL)return true;
queue<TreeNode*> lt,rt;
if(root->left) lt.push(root->left);
if(root->right) rt.push(root->right);
TreeNode* l;
TreeNode* r;
while(!lt.empty() && !rt.empty())
{
l = lt.front();lt.pop();
r = rt.front();rt.pop();
if(l == NULL && r == NULL) continue;
if(l == NULL || r == NULL) return false;
if(l->val != r->val) return false;
lt.push(l->left);
lt.push(l->right);
rt.push(r->right);
rt.push(r->left);
}
if(lt.empty() && rt.empty())
return true;
else
return false;
}
};
错误的方案:
由于是一个对称的树,中序遍历的话,得到的序列关于中心对称。
但如果是{1,2,3,3,#,2,#} 例子,得到的中序遍历为32123。但这棵树不是对称树。不能想当然的这样认为。