ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

算法:对称的二叉树

2022-07-21 23:00:26  阅读:139  来源: 互联网

标签:right TreeNode return 算法 二叉树 对称 null root left


问题

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

解决

//定义二叉树结构
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

//1、递归
class  Solution{
    public boolean isSymmetric(TreeNode root){
         if(root==null) return true;         //如果二叉树为空,则是对称的
         return check(root,root);
    }
    public boolean check(TreeNode r1,TreeNode r2){
        if(r1==null&&r2==null) return true;
        if(r1==null||r2==null) return false;        //这两句是如果r1和r2同时为空则返回true,只有其中一个是空返回false

        return r1.val==r2.val&&check(r1.left,r2.right)&&check(r1.right,r2.left);        //如果是对称的话,一棵树的左子树总是等于另一颗树右子树
    }
}
  • 递归的时间复杂度和空间复杂度

//2、迭代(首先我们引入一个队列,这是把递归程序改写成迭代程序的常用方法)
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return check(root, root);
    }

    public boolean check(TreeNode u, TreeNode v) {
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.offer(u);     //添加一个元素并返回true,如果已满返回false
        q.offer(v);
        while (!q.isEmpty()) {
            u = q.poll();   //移除并返问队列头部的元素    如果队列为空,则返回null
            v = q.poll();
                            //判断不是对称树的条件
            if (u == null && v == null) {
                continue;
            }
            if ((u == null || v == null) || (u.val != v.val)) {
                return false;
            }

                   //这里有点难理解,如果是原树是对称的,那么它的每相邻两棵树之间,1树的左孩子等于2树的右孩子,1树的右孩子等于2树的左孩子。
            q.offer(u.left);  
            q.offer(v.right);

            q.offer(u.right);
            q.offer(v.left);
        }
        return true;
    }
}


  • 迭代的时间复杂度和空间复杂度

 //3、通过创建镜像,比较原相和镜像是否相同判断二叉树是否对称(特别注意克隆部分,不克隆会导致原相变成镜像)
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root==null) return true;         //如果二叉树为空,则是对称的
        //获得二叉树的镜像
        TreeNode curroot=cloneTree(root);
        TreeNode newroot=isSymmetricCopy(curroot);

        return check(root,newroot);
    }

    public TreeNode isSymmetricCopy(TreeNode root){
        if(root==null)  return root;
        
        TreeNode left=isSymmetricCopy(root.left);           //获得左子树的镜像
        TreeNode right=isSymmetricCopy(root.right);         //获得右子树的镜像

        root.left=right;                //简化右子树的镜像作为左子树
        root.right=left;                //简化右子树的镜像作为右子树

        return root;
    }

    public boolean check(TreeNode root,TreeNode newroot){   //无法比较,因为root和newroot是同一个树

        if (root == null && newroot == null) {
            return true;
        }
        if (root == null || newroot == null) {
            return false;
        }
        return check(root.left,newroot.left)&&check(root.right,newroot.right)&&root.val==newroot.val;        
        
    }
    public  TreeNode cloneTree(TreeNode root){
        TreeNode node=null;
        if(root==null) return null;
        node=new TreeNode(root.val);
        node.left=cloneTree(root.left);
        node.right=cloneTree(root.right);

        return node;
    }
    
}
  • 方法三的时间复杂度和空间复杂度:O(N) O(N),但是常数上有区别
//试错
//4、仅仅根据先序的话还是会出现错误
class Solution{
    public boolean isSymmetric(TreeNode root){
         if(root==null) return true;         //如果二叉树为空,则是对称的
          ArrayList r1=new ArrayList<>();
        ArrayList r2=new ArrayList<>();
        ArrayList l1= preOrderRecur(root,r1);
        int size=r1.size();
        TreeNode newroot=isSymmetricCopy(root);
        ArrayList l2=preOrderRecur(newroot,r2);
        for (int i = 0; i < size; i++) {
            if (l1.get(i) != l2.get(i)) {
                return false;
            }
        }
        return true;
    }
    
    //获得二叉树镜像方法
    public static TreeNode isSymmetricCopy(TreeNode root){
        if(root==null)  return root;

        TreeNode left=isSymmetricCopy(root.left);           //获得左子树的镜像
        TreeNode right=isSymmetricCopy(root.right);         //获得右子树的镜像

        root.left=right;                //简化右子树的镜像作为左子树
        root.right=left;                //简化右子树的镜像作为右子树

        return root;
    }

     //先序遍历二叉树
    public static ArrayList preOrderRecur(TreeNode root, ArrayList list) {
        if (root == null) {
            return list;
        }
//        System.out.print(root.val+ " ");

        list.add(root.val);
        preOrderRecur(root.left,list);
        preOrderRecur(root.right,list);
        return list;
    }
}

标签:right,TreeNode,return,算法,二叉树,对称,null,root,left
来源: https://www.cnblogs.com/zhangsanM/p/16503958.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有