给你一个二叉树的根节点 root
, 检查它是否轴对称。
示例 1:
**输入:** root = [1,2,2,3,4,4,3]
**输出:** true
示例 2:
**输入:** root = [1,2,2,null,3,null,3]
**输出:** false
提示:
树中节点数目在范围 [1, 1000]
内
-100 <= Node.val <= 100
进阶: 你可以运用递归和迭代两种方法解决这个问题吗?
递归实现 乍一看无从下手,但用递归其实很好解决。 根据题目的描述,镜像对称,就是左右两边相等,也就是左子树和右子树是相当的。 注意这句话,左子树和右子相等,也就是说要递归的比较左子树和右子树。 我们将根节点的左子树记做 left
,右子树记做 right
。比较 left
是否等于 right
,不等的话直接返回就可以了。 如果相当,比较 left
的左节点和 right
的右节点,再比较 left
的右节点和 right
的左节点 比如看下面这两个子树(他们分别是根节点的左子树和右子树),能观察到这么一个规律: 左子树 $2$ 的左孩子 == 右子树 $2$ 的右孩子 左子树 $2$ 的右孩子 == 右子树 $2$ 的左孩子
1 2 3 4 5 2 2 / \ / \ 3 4 4 3 / \ / \ / \ / \ 8 7 6 5 5 6 7 8
根据上面信息可以总结出递归函数的两个条件: 终止条件:
left
和 right
不等,或者 left
和 right
都为空
递归的比较 left
,left
和 right.right
,递归比较 left
,right
和 right.left
动态图如下:
算法的时间复杂度是 $O(n)$,因为要遍历 $n$ 个节点 空间复杂度是 $O(n)$,空间复杂度是递归的深度,也就是跟树高度有关,最坏情况下树变成一个链表结构,高度是$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 class Solution { public boolean isSymmetric (TreeNode root) { if (root==null ) { return true ; } return dfs(root.left,root.right); } boolean dfs (TreeNode left, TreeNode right) { if (left==null && right==null ) { return true ; } if (left==null || right==null ) { return false ; } if (left.val!=right.val) { return false ; } return dfs(left.left,right.right) && dfs(left.right,right.left); } }
[] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution (object ): def isSymmetric (self, root ): """ :type root: TreeNode :rtype: bool """ if not root: return True def dfs (left,right ): if not (left or right): return True if not (left and right): return False if left.val!=right.val: return False return dfs(left.left,right.right) and dfs(left.right,right.left) return dfs(root.left,root.right)
队列实现 回想下递归的实现: 当两个子树的根节点相等时,就比较: 左子树的 left
和 右子树的 right
,这个比较是用递归实现的。 现在我们改用队列来实现,思路如下: 首先从队列中拿出两个节点(left
和 right
)比较 将 left
的 left
节点和 right
的 right
节点放入队列 将 left
的 right
节点和 right
的 left
节点放入队列 时间复杂度是 $O(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 35 class Solution { public boolean isSymmetric (TreeNode root) { if (root==null || (root.left==null && root.right==null )) { return true ; } LinkedList<TreeNode> queue = new LinkedList <TreeNode>(); queue.add(root.left); queue.add(root.right); while (queue.size()>0 ) { TreeNode left = queue.removeFirst(); TreeNode right = queue.removeFirst(); if (left==null && right==null ) { continue ; } if (left==null || right==null ) { return false ; } if (left.val!=right.val) { return false ; } queue.add(left.left); queue.add(right.right); queue.add(left.right); queue.add(right.left); } return true ; } }
[] 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 class Solution (object ): def isSymmetric (self, root ): """ :type root: TreeNode :rtype: bool """ if not root or not (root.left or root.right): return True queue = [root.left,root.right] while queue: left = queue.pop(0 ) right = queue.pop(0 ) if not (left or right): continue if not (left and right): return False if left.val!=right.val: return False queue.append(left.left) queue.append(right.right) queue.append(left.right) queue.append(right.left) return True