Leetcode No.100&&101相同/对称的树

Leetcode刷题进入到了二叉树的部分,这篇文章总结一下100/101题遇到的递归和迭代解法,两题的思路非常相似。

相同的树

题目大意

给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例1

image.png

示例2
image.png

思路

方法一:递归

递归方法的实现非常简单,首先判断根是否相等,若相等,判断左子树是否相等和右子树是否相等。直接看代码~

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

方法二:迭代

判断两棵二叉树是否相等,可以考虑用层序遍历实现。首先设置两个队列,然后在循环体中对这两个队列进行入队出队操作。每次从两个队列中各弹出一个结点,将它们比较,判断是否相等。若相等,将弹出结点的左孩子、右孩子依次入栈。循环结束条件为队列为空。

//判断结点是否相同
 public boolean check(TreeNode p, TreeNode q) {
        if(p==null && q==null) return true;
        if(p==null || q==null) return false;
        if(p.val == q.val) return true;
        return false;
    }
 public boolean isSameTree(TreeNode p, TreeNode q) {
         if(p==null && q==null) return true;
         if(!check(p,q)) return false;

         ArrayDeque deq1 = new ArrayDeque<>();
         ArrayDeque deq2 = new ArrayDeque<>();
         deq1.addLast(p);
         deq2.addLast(q);
         while(!deq1.isEmpty()) {
             p = deq1.removeFirst();
             q = deq2.removeFirst();
             if(!check(p,q)) return false;
             if(p!=null) {  //p和q都不为Null
                 if(!check(p.left,q.left)) return false;
                 if(p.left!=null) { //p和q的左孩子相同
                     deq1.addLast(p.left);
                     deq2.addLast(q.left);
                  }
                 if(!check(p.right,q.right)) return false;
                 
                 if(p.right!=null) {  //p和q的右孩子相同
                     deq1.addLast(p.right);
                     deq2.addLast(q.right);
                  }
             }
         }
         return true;
    }

对称的树

题目大意

给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。


image.png

思路

判断两棵树是否是镜像对称,需要找到镜像对称的特点:
1.它们两个根节点相同。
2.每棵树的左子树都和另一棵树的右子树相同。

方法一:递归

public  boolean isSymmetric(TreeNode root) {
        if(root==null) return true;
        return mirror(root.left,root.right);
    }
public boolean mirror(TreeNode r1,TreeNode r2) {
        if(r1 == null && r2 == null) return true;
        if(r1 == null || r2 == null) return false;
        if(r1.val != r2.val) return false;
        return  mirror(r1.right,r2.left) &&mirror(r1.left,r2.right);
    }

方法二:迭代

迭代法依旧借助队列结构,首先来看设置两个队列,一个队列存放根节点的左子树,另一个存放根节点的右子树,通过对两个队列进行入栈、出栈操作,判断根节点的左右子树是否镜像对称。注意:若第一个队列的入栈顺序为左、右,那么第二个队列的入栈顺序就是右、左。

public boolean isSymmetric(TreeNode root) {
        Queue deq1 = new LinkedList<>();
        Queue deq2 = new LinkedList<>();
        deq1.add(root);
        deq2.add(root);
        while(!deq1.isEmpty()) {
            TreeNode p = deq1.poll();
            TreeNode q = deq2.poll();
            if(p==null && q==null) continue;
            if(p==null || q==null) return false;
            if(p.val!= q.val) return false;
            deq1.offer(p.left);
            deq1.offer(p.right);
            deq2.offer(q.right);
            deq2.offer(q.left);
        }
        return true;
    }

上一版设置了两个队列,其实可以优化为一个队列。具体看下面的代码。

public boolean isSymmetric(TreeNode root) {
    Queue q = new LinkedList<>();
    q.add(root);
    q.add(root);
    while (!q.isEmpty()) {
        TreeNode t1 = q.poll();
        TreeNode t2 = q.poll();
        if (t1 == null && t2 == null) continue;
        if (t1 == null || t2 == null) return false;
        if (t1.val != t2.val) return false;
        q.add(t1.left);
        q.add(t2.right);
        q.add(t1.right);
        q.add(t2.left);
    }
    return true;
    }

原理一模一样的。

你可能感兴趣的:(Leetcode No.100&&101相同/对称的树)