题目
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
进阶:
你可以运用递归和迭代两种方法解决这个问题吗?
解题思路
解法一:递归法
1)如果根节点为空,则是对称的;
2)如果根节点不为空,那么就看它的左右子树是否对称:
2.1)左右子树都为空,则是对称的;
2.2)左右子树不全为空,或者左右子树根节点的值不相等,那么就不是对称的;
2.3)左右子树都不为空,且左右子树根节点的值相等,那么就继续递归判断左子树的左节点和右子树的右节点是否对称,左子树的右节点和右子树的左节点是否对称。
复杂度分析:(假设树上一共有 n 个节点)
时间复杂度:这里遍历了这棵树,渐进时间复杂度为 O(n)。
空间复杂度:这里的空间复杂度和递归使用的栈空间有关,这里递归层数不超过 n,故渐进空间复杂度为 O(n)。
解法二:迭代法
首先我们引入一个队列,初始化时我们把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。
复杂度分析
时间复杂度:O(n),同「解法一」。
空间复杂度:这里需要用一个队列来维护节点,每个节点最多进队一次,出队一次,队列中最多不会超过 n 个点,故渐进空间复杂度为 O(n)。
代码
解法一:递归法
Python代码如下:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
if root == None:
return True
else:
return self.helper(root.left, root.right)
def helper(self, l, r):
if l == None and r == None:
return True
if l == None or r == None or l.val != r.val:
return False
return self.helper(l.left, r.right) and self.helper(l.right, r.left)
Java代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null){
return true;
}else{
return helper(root.left, root.right);
}
}
public boolean helper(TreeNode l, TreeNode r){
if(l == null && r == null){
return true;
}
if(l == null || r == null || l.val != r.val){
return false;
}
return helper(l.left, r.right) && helper(l.right, r.left);
}
}
解法二:迭代法:
Python代码如下:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
from collections import deque
queue = deque()
queue.append((root, root))
while queue:
l, r = queue.popleft()
if l == None and r == None:
continue
if l == None or r == None or l.val != r.val:
return False
queue.append((l.left, r.right))
queue.append((l.right, r.left))
return True
Java代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
queue.offer(root);
while(!queue.isEmpty()){
TreeNode u = queue.poll();
TreeNode 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;
}
}