- 剑指Offer28.对称的二叉树
- 题目:
判断一个二叉树是否对称?
- 思路:
1.递归:O(n):二叉树共n个结点,每次调用递归函数isSame都可以完成两个结点的比较,因此最多调用n/2次递归函数(即比较到最后一对结点),最坏情况下O(n):当二叉树退化成两条链表,此时二叉树的深度为n/2,可以使在满足递归条件前提下深度达到最深(若再少一个就会提前return false),这时系统使用O(n)的栈空间,下面为具体解释:
思路:将处于对称位置上的结点两两比较,直至比较到最下层;
class Solution {
private:
bool isSame(TreeNode* l, TreeNode* r) {//判断l子树和r子树是否对称
if (!l && !r) return true;//都为空算对称
else if (!l || !r) return false;//只有一个空肯定不对称
else if (l->val != r->val) return false;//都不为空,但值不相等也不对称
//注意:对称指的是:左的左对比右的右,左的右对比右的左
else return isSame(l->left, r->right) && isSame(l->right, r->left);//说明当前结点对称,就要递归的判断孩子
}
public:
bool isSymmetric(TreeNode* root) {
if (!root) return true;
return isSame(root->left, root->right);//处于对称位置上的结点两两比较
}
};
2.迭代:O(n),O(n)
由于本题目的是两两比较处于对称位置上的节点值,因此可以层序遍历的时候,在入队时,将对称位置上的结点两两入队,到时候就可以成对的取出进行比较;
采用队列,栈,数组均可;
//利用队列,将出于对称位置上的结点两两入队
//栈,甚至数组同理
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if (!root) return true;
queue<TreeNode*> q;
q.push(root->left);
q.push(root->right);
while (!q.empty()) {
for (int i = 0; i < q.size(); ++i) {//这里利用可变的q.size()简化,直至遍历完全部节点才退出dor循环
auto l = q.front();
q.pop();
auto r = q.front();
q.pop();
//中
if (!l && !r) continue;
if ((!l && r) || (l && !r) || (l->val != r->val)) return false;
q.push(l->left);//成对入队
q.push(r->right);
q.push(l->right);//成对入队
q.push(r->left);
}
}
return true;
}
};