给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3]
是对称的。
1 2 3 4 5
| 1 / \ 2 2 / \ / \ 3 4 4 3
|
但是下面这个 [1,2,2,null,3,null,3]
则不是镜像对称的:
进阶:
你可以运用递归和迭代两种方法解决这个问题吗?
如果一个二叉树的左右子树镜像对称,那么这个树镜像对称。两个子树镜像对称有如下性质:
左右两个子树根结点值相等
每个树的右子树与另一个子树的左子树镜像对称
我们可以使用两个指针 p 和 q ,它们最开始都指向根结点,p 右移时, q 左移,p 左移时,q 右移,同时判断 p 和 q 的值是否相等并递归判断它们的子树是否镜像对称。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
class Solution { public boolean isSymmetric(TreeNode root) { return check(root, root); } private boolean check(TreeNode p, TreeNode q){ if(p == null && q == null){ return true; } if(p == null || q == null){ return false; }
return p.val == q.val && check(p.left, q.right) && check(p.right, q.left); } }
|
每个结点遍历一次,时间复杂度 O(n)。递归层数不超过 n 层,渐进空间复杂度为 O(n)。
我们还可以使用一个队列来模拟递归,每次进队列两个二叉树的镜像结点,依次判断它们的值是否相等,直到队列为空。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
class Solution { public boolean isSymmetric(TreeNode root) { return check(root, root); } private boolean check(TreeNode u, TreeNode v){ Queue<TreeNode> queue = new LinkedList<>(); queue.offer(u); queue.offer(v); while(!queue.isEmpty()){ u = queue.poll(); v = queue.poll();
if(u == null && v == null) continue; if((u ==null || v == null) || (u.val != v.val)) return false;
queue.offer(u.left); queue.offer(v.right);
queue.offer(u.right); queue.offer(v.left); } return true; } }
|
每个结点遍历一次,时间复杂度 O(n)。每个结点入队一次,队列中最多 n 个结点,渐进空间复杂度为O(n)。