Symmetric Tree
Given a binary tree, check whether it is a mirror of itself(ie, symmetric around its center)
For example, this tree is symmetric:
1
/ \
2 2
/ \ / \
3 4 4 3
But the following tree is not.
1
/ \
2 2
\ \
3 3
题目翻译: 判断一棵树是不是自己的镜像, 根据以上正反两个例子,我想大家都明白这道题的题目要求了,简单明了.
解题思路: 递归: 这道题没什么特别的地方,现在这里简单的分析一下解题思路,从根节点往下,我们要判断三个条件.
- 左右两个节点的大小是否相同.
- 左节点的左孩子是否和右节点的右孩子相同.
- 左节点的右孩子是否和右节点的左孩子相同.
循环: 这道题的难点在于循环解法, 如果是循环解法,我们必须要用到额外的存储空间用于回溯,关键是对于这道题目, 我们要用多少?要怎么用?要用什么样的存储空间?
递归求解,如果以上三个条件对于每一层都满足,我们就可以认为这棵树是镜像树.
时间复杂度: 递归:本质其实就是DFS,时间复杂度为O(n),空间复杂度O(1) 递归:时间复杂度O(n),空间复杂度O(n)
递归代码如下:
/**
* 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) {
if(root == NULL)
return true;
return Helper(root->left,root->right);
}
bool Helper(TreeNode* left, TreeNode* right)
{
if(left == NULL&&right == NULL)
return true;
else if(left == NULL||right == NULL)
return false;
bool cond1 = left->val == right->val;
bool cond2 = Helper(left->left,right->right);
bool cond3 = Helper(left->right, right->left);
return cond1&&cond2&&cond3;
}
};
循环解法: 我们主要想介绍一下这道题的循环解法,对于循环,我们要满足对于每一层进行check,代替了递归,一般树的循环遍历,我们都是用FIFO的queue来作为临时空间存储变量的,所以这道题我们也选取了queue,但是我们用两个queue,因为我们要对于左右同时进行检查,很显然一个queue是不够的,具体实现细节,咱们还是看代码吧,,我相信代码更能解释方法.
循环代码如下:
/**
* 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) {
if(root == NULL)
return true;
TreeNode* n1 = root->left;
TreeNode* n2 = root->right;
if(!n1&&!n2)
return true;
if((!n1&&n2)||(n1&&!n2))
return false;
queue<TreeNode*> Q1;
queue<TreeNode*> Q2;
Q1.push(n1);
Q2.push(n2);
while(!Q1.empty() && !Q2.empty())
{
TreeNode* tmp1 = Q1.front();
TreeNode* tmp2 = Q2.front();
Q1.pop();
Q2.pop();
if((!tmp1&&tmp2) || (tmp1&&!tmp2))
return false;
if(tmp1&&tmp2)
{
if(tmp1->val != tmp2->val)
return false;
Q1.push(tmp1->left);
Q1.push(tmp1->right); //note: this line we should put the mirror sequence in two queues
Q2.push(tmp2->right);
Q2.push(tmp2->left);
}
}
return true;
}
};