题目:Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).For example, this binary tree is symmetric:题目源自于Leetcode。
1
/ \
2 2
/ \ / \
3 4 4 3
之前错误的思路:先中序遍历,在遍历过程中生成整个树的中序序列,然后判断这个序列是否是回文序列。这个错误在于“二叉树对称”是“中序序列是回文”的充分不必要条件。
//错误方案 class Solution { public: bool isSymmetric(TreeNode *root) { if(root == NULL) return true; vector<int> v; fun(root, v); int n = v.size(); if(n%2==0) //必定是奇数个元素才能对称 return false; int i; for(i=1;i<=n/2;i++) //判断是否是回文 { if(v[n/2+i] != v[n/2-i]) return false; } return true; } void fun(TreeNode *root, vector<int> &v) { if(root != NULL) { fun(root->left, v); v.push_back(root->val); fun(root->right, v); } } };
思路1:递归思想,对称二叉树的左右两个子树一定是镜面对称的。对于镜面对称判断其左右结点的孩子是否是镜面的,递归进行下去。
class Solution { public: bool isSymmetric(TreeNode *root) { if(root == NULL) return true; return isSym(root->left, root->right); } bool isSym(TreeNode *p1, TreeNode *p2) { if(p1 == NULL && p2 == NULL) return true; else if(p1 == NULL || p2 == NULL) return false; else if(p1->val == p2->val) { return isSym(p1->left, p2->right) && isSym(p1->right, p2->left); } else return false; } };
思路2:先将原二叉树镜面对称过来变成另一个二叉树,然后判断两个二叉树是否是完全相同的。
class Solution { public: bool isSymmetric(TreeNode *root) { TreeNode *mi = mirror(root); return isEqual(mi, root); } TreeNode* mirror(TreeNode *root) //生成镜像化的二叉树 { if(root == NULL) return NULL; TreeNode *nroot = new TreeNode(root->val); nroot->left = mirror(root->right); nroot->right = mirror(root->left); return nroot; } bool isEqual(TreeNode *p1, TreeNode *p2) //判断两个二叉树是否完全相等 { if(p1 == NULL && p2 == NULL) return true; else if(p1 == NULL || p2 == NULL) return false; if(p1->val == p2->val) return isEqual(p1->left, p2->left) && isEqual(p1->right, p2->right); else return false; } };
思路3:层序遍历。层序遍历过程中不漏过任何一个空的孩子,直到最底层全部为空节点才结束遍历。每一层结束时判断一次该层的结点是否是回文。
该方法的时间复杂度并不高,可是我的实现却超时了。
class Solution { public: bool isSymmetric(TreeNode *root) { queue<TreeNode *> q; vector<int> level; q.push(root); TreeNode *enode = new TreeNode(-1);//每一层结束的标记 q.push(enode); int count = 0;//记录是否到达全部为空节点的最底层 while(!q.empty()) { TreeNode* tmp = q.front(); q.pop(); if(tmp == enode) { if(count == 0) return true; if(!isPalin(level)) return false; level.clear(); count = 0; if(!q.empty()) { q.push(enode); continue; } else return true; } else if(tmp == NULL) { level.push_back(-1); q.push(NULL); q.push(NULL); } else { q.push(tmp->left); q.push(tmp->right); level.push_back(tmp->val); count++; } } } bool isPalin(vector<int> &level) { int left = 0, right = level.size()-1; while(left < right) { if(level[left++] != level[right--]) return false; } return true; } };