思路
- 对称的定义,根节点相等,左右子树对称,因此可以使用递归遍历
- 递归截止条件
1)根节点值相等
3)使用两个指针,一个左子树遍历,一个右子树遍历,如果这两个指针始终相等,则表示左右子树是对称的
/**
* 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) {
// 这个思路很巧妙,通过检查根节点的两个子树来判断是否相等
// 递归判断左右节点是否相等
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);
}
}
思路2
- 根据观察不难发现,其实对称树存在一个特点,使用层次遍历的时候,对称树的每层都是对称的,因此想要判断一个对称树就可以通过以下两步来实现
1)层次遍历每一层
2)根据判断步骤一的每层元素是否对称来判断该树是否对称
/**
* 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) {
// 1. 层序遍历判断是否对称
if (root == null) return true;
// 层序遍历的时候通常需要借助一个队列来对元素进行存放
LinkedList<TreeNode> queue = new LinkedList();
queue.add(root);
// 默认对称
boolean isSymmetric = true;
// 外层循环每次处理一层
while (!queue.isEmpty()) {
// 判断不对称直接跳出
if (!isSymmetric) break;
// 每层的节点
int size = queue.size();
ArrayList<Integer> nums = new ArrayList();
for(int i = 0;i < size; i++) {
// 除了第一层需要是1个元素,其他的层数量应该为偶数
TreeNode t = queue.poll();
// 这里需要注意空节点null是需要入栈的,因为如果只存在一边子树元素,不能判断是否是对称
if (t == null) {
nums.add(null);
}else{
nums.add(t.val);
}
if(t!= null) {
queue.add(t.left);
queue.add(t.right);
}
}
int left = 0;
int right = size - 1;
// 头尾双指针判断
while (left<=right) {
if (nums.get(left) != nums.get(right)) {
isSymmetric = false;
break;
}
left++;
right--;
}
}
return isSymmetric;
}
}
Q.E.D.