题目大意:给定一个二叉树,判断该二叉树是否是对称的。
理解:1)二叉树从root所在的轴,两边树是否一样(对称);
2)题目建议最好用递归和迭代两种方法实现。
本人首先想到是迭代的方法:用层次遍历的方法,判断二叉树的每一层是否对称(分治)。
实现:迭代的方法时间复杂度是O(n),空间复杂度是O(n + logn)。
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isSym(ArrayList<Long> arr) { // 判断每个数组是否对称
if(arr.size() % 2 == 1) return false;
int low = 0, high = arr.size() - 1;
while(low < high) {
if(!arr.get(low).equals(arr.get(high))) return false; // 此处对于对象的比较要用equals,"=="只对地址进行比较
low ++;
high --;
}
return true;
}
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
if(root.left == null && root.right == null) return true;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
ArrayList<Long> arr = new ArrayList<Long>();
int visit = 1, nextVisit = 0;
while(!queue.isEmpty()) {
TreeNode front = queue.poll();
visit --;
if(front.left != null) {
nextVisit ++;
queue.offer(front.left);
long value = front.left.val + 0L;
arr.add(value);
}
else arr.add(Long.MAX_VALUE);
if(front.right != null) {
nextVisit ++;
queue.offer(front.right);
long value = front.right.val + 0L;
arr.add(value);
}
else arr.add(Long.MAX_VALUE);
if(visit == 0) {
if(nextVisit == 0) break; // 是否已判断完
if(!isSym(arr)) return false; // 判断二叉树的每一层是否对称
visit = nextVisit;
nextVisit = 0;
arr = new ArrayList<Long>();
}
}
return true;
}
}
第二种方法是构建一个与原树对称的树,判断这两棵树是否相等。时间复杂度是O(n),空间复杂度也是O(n)。
实现:
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isSym(TreeNode root, TreeNode root1) {
if(root == null && root1 == null) return true;
if(root == null || root1 == null) return false;
if(root.val != root1.val) return false;
return isSym(root.left, root1.left) && isSym(root.right, root1.right);
}
public TreeNode buildSymTree(TreeNode root) {
if(root == null) return root;
TreeNode root1 = new TreeNode(root.val);
root1.left = buildSymTree(root.right);
root1.right = buildSymTree(root.left);
return root1;
}
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
TreeNode root1 = buildSymTree(root); // 构建对称树
return isSym(root, root1);
}
}
第三种方法是递归的方法:是能想到的最好的方法了。
代码简洁了很多,这时的时间复杂度是O(n),空间复杂度是0.
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isSym(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 isSym(left.left, right.right) && isSym(left.right, right.left);
}
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
if(root.left == null && root.right == null) return true; // 此处先把根的所有情况先考虑完,然后再分别遍历左子树和右子树是否对称
return isSym(root.left, root.right); // 这样就保证对树只遍历一遍
}
}