剑指 Offer 28. 对称的二叉树

目录

一、题目

二、递归写法

三、使用辅助队列

四、使用辅助栈


一、题目

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

     1
   /   \
  2    2
 / \    / \
3  4 4  3

限制:

0 <= 节点个数 <= 1000

示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true


示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false
 

二、递归写法

思路:若树的做左子树与右子树镜像对称、则此树对称。

判断两棵树镜像对称:

                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) {
        // 特殊情况
        if(root==null){
            return true;
        }
        return isMirror(root.left, root.right);
    }

    public boolean isMirror(TreeNode left, TreeNode right) {
        if (left == null && right == null) {
            return true;
        }
        if (left == null || right == null) {
            return false;
        }
        return left.val == right.val && isMirror(left.left, right.right) && isMirror(left.right, right.left);
    }
}

时间复杂度O(N),N为结点数。

空间复杂度O(N),N为数的层数。 

执行结果

 

三、使用辅助队列

思路:

        每次两个结点并比较它们的值(两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。

class Solution {
    public boolean isSymmetric(TreeNode root) {
        // 特殊情况
        if(root==null){
            return true;
        }

        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        // 左右子树入队
       queue.offer(root.left);
       queue.offer(root.right);
        while (!queue.isEmpty()) {
            // 先入先出
           TreeNode left = queue.poll();
           TreeNode right = queue.poll();
            if (left == null && right == null) {
                continue;
            }
            // 判断队列连续两个元素的值
            if ((left == null || right == null) || (left.val != right.val)) {
                return false;
            }

            // 左右子树子节点相反顺序入队
            queue.offer(left.left);
            queue.offer(right.right);

            queue.offer(left.right);
            queue.offer(right.left);
        }
        return true;
    }



}

注意:

入队:add(e)、offer(e),插入失败前者会抛异常

出队:remove()、poll(),删除失败前者会抛异常

抛出:


        ClassCastException – 如果指定元素的类阻止将其添加到此队列
        NullPointerException – 如果指定的元素为null,并且此队列不允许null元素
        IllegalArgumentException –如果此元素的某些属性阻止将其添加到此队列

 执行结果

四、使用辅助栈

class Solution {
    public boolean isSymmetric(TreeNode root) {
        // 特殊情况
        if(root==null){
            return true;
        }

        Stack<TreeNode> stack = new Stack<>();
        // 左右子树入栈
        stack.push(root.left);
        stack.push(root.right);
        while (!stack.isEmpty()) {

            TreeNode  right = stack.pop();
            TreeNode  left = stack.pop();

            if (left == null && right == null){
                    continue;
            } 
            // 判断连续连个元素的值
            if (left == null || right == null || (left.val != right.val)) {
                    return false;
            }

            // 左右子树的左右结点入栈
            stack.push(left.left);
            stack.push(right.right);
        
            stack.push(right.left);
            stack.push(left.right);
        }
        return true;
    }
}

执行结果

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值