day30 JZ28 对称的二叉树(Java)

114 阅读3分钟

题目来源: JZ28 对称的二叉树

题目描述:

  • 描述: 给定一棵二叉树,判断其是否是自身的镜像(即:是否对称) 数据范围: 节点数满足 0≤n≤1000,节点上的值满足 ∣val∣≤1000 要求: 空间复杂度O(n),时间复杂度O(n)
    • 比如:下面这棵二叉树是对称的
      • A22A794C036C06431E632F9D5E2E298F.png
    • 下面这棵二叉树不对称。
      • 3304ABDD147D8E140B2CEF3201BD8372.png
示例1:
输入:{1,2,2,3,4,4,3}
返回值:true

示例2:
输入:{8,6,9,5,7,7,5}
输出:false

思路:层次遍历

  • 知识点:队列 思路:
    • 题目要求的判断二叉树是否对称,而我们很清楚,如果二叉树是对称的,那么二叉树的每一层都是回文的情况,即两边是相互对应相等的,即使是空节点,那也是对应着的
    • 顾名思义,如果对二叉树进行层次遍历时,对于每一层,不管是从左往右还是从右往左,得到的结果都是一样的
    • 此时就需要使用到队列了,我们知道,队列的特点是先进先出,如果是从左往后遍历二叉树的每一层,那么加入队列的元素顺序就是从左往右的,如果是从右往左遍历,当然队列也是从右往左
    • 而对于二叉树的层次遍历,如何进入下一层,也是通过队列就可以实现了
    • 而且我们不需要两个层次遍历都完整地遍历二叉树,只需要一半就行了,从左往右遍历左子树,从右往左遍历右子树,各自遍历一半相互比对,因为遍历到另一半都已经检查过了。
  • 具体做法:
    • 1.优先进行判断链表是否为空链表,如果是空链表,那么直接就是对称
    • 2.我们需要准备两个队列,分别作为从左往右遍历与从右往左遍历的辅助,将左节点加入第一个队列,右节点加入第二个队列
    • 3.遍历结束也没有检查到不匹配,说明就是对称的。
  • 图示:

18C2F6B30AC832D8FD5F419CF8A9D094.gif

具体实现:

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 天,点击查看活动详情