1.题目描述:
给你一个二叉树的根节点root,检查它是否轴对称。
2.翻转树的递归解法:
自己在做这道题目的时候,发现递归第二步,每级递归需要做什么不好写,于是想反转右子树后再判断与左子树是否一致即可,翻转的题目正好做过leetcode226. 翻转二叉树。这种方法时间复杂度近似O(n),空间复杂度最差O(n)。直接看代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return false;
return symmetricTree(root.left,reverseTree(root.right));
}
public TreeNode reverseTree(TreeNode root){
if(root == null) return null;
TreeNode l = root.left;
root.left = root.right;
root.right = l;
reverseTree(root.left);
reverseTree(root.right);
return root;
}
public boolean symmetricTree(TreeNode node1,TreeNode node2){
if(node1 == null && node2 == null) return true;
if(node1 == null || node2 == null) return false;
return node1.val == node2.val && symmetricTree(node1.left,node2.left) && symmetricTree(node1.right,node2.right);
}
}
3.普通的递归解法:借助两次root,递归判断p左子树与q右子树是否镜像,p右子树与q左子树是否镜像。时间复杂度近似O(n),空间复杂度链表最差O(n),代码如下:
class Solution {
public boolean isSymmetric(TreeNode root) {
return check(root, root);
}
public 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);
}
}
4.在此基础上,BFS解法:
class Solution {
public boolean isSymmetric(TreeNode root) {
return check(root, root);
}
public boolean check(TreeNode u, TreeNode v) {
Queue q = new LinkedList();
q.offer(u);
q.offer(v);
while(!q.isEmpty()){
u = q.poll();
v = q.poll();
if(u == null && v == null) continue;//重点注意
if((u == null || v == null) || (u.val != v.val)) return false;
q.offer(u.left);
q.offer(v.right);
q.offer(u.right);
q.offer(v.left);
}
return true;
}
}
5.二刷递归:递归比较左边的左边和右边的左边,左边的右边和右边的左边即可。
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return dfs(root.left, root.right);
}
public boolean dfs(TreeNode left, TreeNode right) {
if (left == null && right == null) return true;
if (left == null || right == null || left.val != right.val) return false;
return dfs(left.left, right.right) && dfs(left.right, right.left);
}
}
迭代:与层序遍历顺序不同,队列里一次放两个对称性的位置在同时弹出比较。
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
Queue queue = new LinkedList<>();
queue.offer(root.left);
queue.offer(root.right);
while (!queue.isEmpty()) {
TreeNode n1 = queue.poll();
TreeNode n2 = queue.poll();
if (n1 == null && n2 == null) continue;
if (n1 == null || n2 == null || n1.val != n2.val) return false;//判断逻辑与递归一致
queue.offer(n1.left);//与普通层序遍历不同(不用考虑是否为null)
queue.offer(n2.right);
queue.offer(n1.right);
queue.offer(n2.left);
}
return true;
}
}