题目来源: JZ28 对称的二叉树
题目描述:
- 描述: 给定一棵二叉树,判断其是否是自身的镜像(即:是否对称)
数据范围: 节点数满足 0≤n≤1000,节点上的值满足 ∣val∣≤1000
要求: 空间复杂度O(n),时间复杂度O(n)
- 比如:下面这棵二叉树是对称的
- 下面这棵二叉树不对称。
- 比如:下面这棵二叉树是对称的
示例1:
输入:{1,2,2,3,4,4,3}
返回值:true
示例2:
输入:{8,6,9,5,7,7,5}
输出:false
思路:层次遍历
- 知识点:队列 思路:
- 题目要求的判断二叉树是否对称,而我们很清楚,如果二叉树是对称的,那么二叉树的每一层都是
回文的情况,即两边是相互对应相等的,即使是空节点,那也是对应着的 - 顾名思义,如果对二叉树进行层次遍历时,对于每一层,不管是
从左往右还是从右往左,得到的结果都是一样的 - 此时就需要使用到队列了,我们知道,队列的特点是
先进先出,如果是从左往后遍历二叉树的每一层,那么加入队列的元素顺序就是从左往右的,如果是从右往左遍历,当然队列也是从右往左 - 而对于二叉树的层次遍历,如何进入下一层,也是通过队列就可以实现了
- 而且我们不需要两个层次遍历都完整地遍历二叉树,只需要一半就行了,从左往右遍历左子树,从右往左遍历右子树,各自遍历一半相互比对,因为遍历到另一半都已经检查过了。
- 题目要求的判断二叉树是否对称,而我们很清楚,如果二叉树是对称的,那么二叉树的每一层都是
- 具体做法:
- 1.优先进行判断链表是否为空链表,如果是空链表,那么直接就是对称
- 2.我们需要准备两个队列,分别作为从左往右遍历与从右往左遍历的辅助,将左节点加入第一个队列,右节点加入第二个队列
- 3.遍历结束也没有检查到不匹配,说明就是对称的。
- 图示:
具体实现:
import java.util.*;
public class Solution {
boolean isSymmetrical(TreeNode pRoot) {
//空树为对称的
if(pRoot == null)
return true;
//辅助队列用于从两边层次遍历
Queue<TreeNode> q1 = new LinkedList<TreeNode>();
Queue<TreeNode> q2 = new LinkedList<TreeNode>();
q1.offer(pRoot.left);
q2.offer(pRoot.right);
while(!q1.isEmpty() && !q2.isEmpty()){
//分别从左边和右边弹出节点
TreeNode left = q1.poll();
TreeNode right = q2.poll();
//都为空暂时对称
if(left == null && right == null)
continue;
//某一个为空或者数字不相等则不对称
if(left == null || right == null || left.val != right.val)
return false;
//从左往右加入队列
q1.offer(left.left);
q1.offer(left.right);
//从右往左加入队列
q2.offer(right.right);
q2.offer(right.left);
}
//都检验完都是对称的
return true;
}
}
- 复杂度分析:
- 时间复杂度O(n),其中n为二叉树的节点数,相当于遍历二叉树全部节点
- 空间复杂度O(n),两个辅助队列的最大空间为n
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情”