Description
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree [1,2,2,3,4,4,3] is symmetric:
1
/ \
2 2
/ \ / \
3 4 4 3
But the following [1,2,2,null,3,null,3] is not:
1
/ \
2 2
\ \
3 3
Note
- Bonus points if you could solve it both recursively and iteratively.
Solution
这种关于二叉树的题一般都有很多种解题方式,我想到的第一种方式很直观,就是将前序遍历和反方向的前序遍历的结果放入两条ArrayList
,然后比较是否相同即可:
public class Solution {
public boolean isSymmetric(TreeNode root) {
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
preOrder(root, list1);
mirrorOrder(root, list2);
return list1.equals(list2);
}
private void preOrder(TreeNode node, List<Integer> list) {
if(node == null) {
list.add(null);
return;
}
list.add(node.val);
preOrder(node.left, list);
preOrder(node.right, list);
}
private void mirrorOrder(TreeNode node, List<Integer> list) {
if(node == null) {
list.add(null);
return;
}
list.add(node.val);
mirrorOrder(node.right, list);
mirrorOrder(node.left, list);
}
}
这种方式理论上时间复杂度为O(n),但还是做了许多没必要的工作,而且代码不够简洁,因此需要继续改进。
判断一个树是否是对称的,我们可以将根节点的两个子树拆分出来,首先判断这两颗子树的根节点是否相同,然后递归地判断第一棵树的左子树与第二棵树的右子树是否是对称的和第一棵树的右子树与第二棵树的左子树是否是对称的。用递归实现如下:
public class Solution3 {
public boolean isSymmetric(TreeNode root) {
if(root == null)
return true;
return isMirror(root.left, root.right);
}
private boolean isMirror(TreeNode t1, TreeNode t2){
if(t1 == null || t2 == null)
return t1 == t2;
return (t1.val == t2.val) && isMirror(t1.left, t2.right) && isMirror(t1.right, t2.left);
}
}
该方法本质上就是不停地在两棵子树中判断根节点是否相同,我们还可以使用队列来保存每一层的结果(重点在于队列添加节点的顺序),这样就可以通过循环来实现:
public class Solution4 {
public boolean isSymmetric(TreeNode root) {
if(root == null)
return true;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root.left);
queue.add(root.right);
while(!queue.isEmpty()) {
TreeNode node1 = queue.poll();
TreeNode node2 = queue.poll();
if(node1 == null && node2 == null) continue;
if(node1 == null || node2 == null) return false;
if(node1.val != node2.val) return false;
queue.add(node1.left);
queue.add(node2.right);
queue.add(node1.right);
queue.add(node2.left);
}
return true;
}
}