这道题是树的题目,本质上还是树的遍历。这里无所谓哪种遍历方式,只需要对相应结点进行比较即可。一颗树对称其实就是看左右子树是否对称,一句话就是左同右,右同左,结点是对称的相等。题目中也要求了递归和非递归的解法,关于这个我们已经介绍过很多次了,不了解的朋友可以看看Binary Tree Inorder Traversal,里面介绍了几种树的遍历方式。这道题目也就是里面的程序框架加上对称性质的判断即可。遍历这里就不多说了,我们主要说说结束条件,假设到了某一结点,不对称的条件有以下三个:(1)左边为空而右边不为空;(2)左边不为空而右边为空;(3)左边值不等于右边值。根据这几个条件在遍历时进行判断即可。算法的时间复杂度是树的遍历O(n),空间复杂度同样与树遍历相同是O(logn)。递归方法的代码如下:
递归:
<span style="font-family:Microsoft YaHei;font-size:14px;">/**
* Definition for binary tree
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool symmetric(struct TreeNode *lt,struct TreeNode *rt){
if(!lt && !rt) return true;
if(lt && !rt || !lt && rt || lt->val != rt->val) return false;
return symmetric(lt->left,rt->right) && symmetric(lt->right,rt->left);
}
bool isSymmetric(struct TreeNode *root) {
if(root == NULL) return true;
return symmetric(root->left,root->right);
}</span>
下面的非递归方法是使用层序遍历(使用队列来实现)来判断对称性质,代码如下:
<span style="font-family:Microsoft YaHei;font-size:14px;">/**
* 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;
queue<TreeNode *> q1,q2;
q1.push(root->left);
q2.push(root->right);
TreeNode *left,*right;
while(!q1.empty() && !q2.empty()){
left = q1.front();
q1.pop();
right = q2.front();
q2.pop();
if(left == NULL && right == NULL) //这个判断一定要在下一个判断之前,因为下一个判断极有可能走到left->val这一步
continue;
if(!left && right || left && !right || left->val != right->val)
return false;
q1.push(left->left);
q1.push(left->right);
q2.push(right->right);
q2.push(right->left);
}
return true;
}
};</span>
参考:http://blog.csdn.net/linhuanmars/article/details/23072829