算法:对称的二叉树


问题

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

解决

//定义二叉树结构
/**
 * 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;
    }
}

原创文章,作者:506227337,如若转载,请注明出处:https://blog.ytso.com/275946.html

(0)
上一篇 2022年7月22日
下一篇 2022年7月22日

相关推荐

发表回复

登录后才能评论