59 对称的二叉树 《剑指offer》 101. 对称二叉树《LeetCode》

62 篇文章 1 订阅
44 篇文章 0 订阅

题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
建议打开这个以及101的那篇对着看。

import java.util.*;
public class Solution {
    ArrayList<Integer> list1 = new ArrayList();
    ArrayList<Integer> list2 = new ArrayList();
    public void unPreOrder(TreeNode root){
        if(root == null)
            list1.add(null);
       else{
            list1.add(root.val);
            unPreOrder(root.right);
            unPreOrder(root.left);
       }
    }
    public void preOrder(TreeNode root){
        if(root == null)
            list2.add(null);
        else{
            list2.add(root.val);            
            preOrder(root.left);
            preOrder(root.right);
        }

    }
    boolean isSymmetrical(TreeNode pRoot)
    {
        if(pRoot == null)
            return true;
        unPreOrder(pRoot);
        preOrder(pRoot);    
        for(int i=0;i<list1.size();i++){
            if(list1.get(i) != list2.get(i))
                return false;
        }
        return true;
    }
}

本来想使用一个镜像函数来做,发现使用后,原来的树节点就变成它的镜像了,无法进行比较。
做一个先序遍历的对称遍历,然后比较他们的元素。为了避免树中所有节点都相同,存储的时候还带了null节点。
可以通过比较二叉树的前序遍历和二叉树对称前序遍历来判断二叉树是不是对称的。
还是那一套,一种是先遍历,保存在数组中,然后进行处理(判断两数组是否相同);

另一种是在遍历的同时进行判断处理。
意识到镜像是当前二叉树将所有的左右节点进行交换而生成的,所以:

public class Solution {

    boolean isSymmetrical(TreeNode root1,TreeNode root2){
        if(root1 == null && root2 == null)
            return true;
        if(root1 == null || root2 == null)
            return false;
            //下面这两段很重要
        if(root1.val != root2.val)
            return false;
        return isSymmetrical(root1.left,root2.right)  
                             && isSymmetrical(root1.right,root2.left); 
    }
    boolean isSymmetrical(TreeNode pRoot)
    {
        return isSymmetrical(pRoot,pRoot);
    }
}
   if(root1.val != root2.val)
            return false;
        return isSymmetrical(root1.left,root2.right)  
                             && isSymmetrical(root1.right,root2.left); 

也可以写成

return root1.val == root2.val && isSymmetrical(root1.left,root2.right)  
                             && isSymmetrical(root1.right,root2.left); 

LeetCode的代码:

给定一个二叉树,检查它是否是镜像对称的。

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

    1
   / \
  2   2
 / \ / \
3  4 4  3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

    1
   / \
  2   2
   \   \
   3    3
class Solution {
    public boolean leftEqualsRight(TreeNode root1,TreeNode root2) {
        if(root1 == null && root2 == null)
            return true;
        if(root1 == null || root2 == null)
            return false;

        if(root1.val != root2.val)
            return false;
        return leftEqualsRight(root1.left,root2.right) && leftEqualsRight(root1.right,root2.left);
    }

    public boolean isSymmetric(TreeNode root) {
        if(root == null)
            return true;
        return leftEqualsRight(root,root);
    }
}

注意: //if(root1.val == root2.val) // return true;显然这个不是递归的终结条件!

迭代:

class Solution {
    public boolean leftEqualsRight(TreeNode root1,TreeNode root2) {
        Stack<TreeNode> stack1 = new Stack();
        Stack<TreeNode> stack2 = new Stack();
        TreeNode p = root1,q = root2;
        while((!stack1.isEmpty() && !stack2.isEmpty()) || (p != null && q != null)){
            if(p != null && q != null){
                stack1.push(p);
                p = p.left;
                stack2.push(q);
                q = q.right;
            }else if((p == null&& q != null) || (p != null&& q == null)){
                return false;
            }else{
                p = stack1.pop();
                q = stack2.pop();
                if(p.val != q.val)
                    return false;
                p = p.right;
                q = q.left;
           }            
        }
        return true;
    }

    public boolean isSymmetric(TreeNode root) {
        if(root == null)
            return true;
        return leftEqualsRight(root,root);
    }
}

先序遍历:这里请重点关注

class Solution {
    public boolean leftEqualsRight(TreeNode root1,TreeNode root2) {
        Stack<TreeNode> stack1 = new Stack();
        Stack<TreeNode> stack2 = new Stack();
        stack1.push(root1);
        stack2.push(root2);
        while(!stack1.isEmpty() && !stack2.isEmpty()){
            TreeNode p = stack1.pop();
            TreeNode q = stack2.pop();
            if(p.val != q.val 
            || (p.right == null && q.left != null) 
            || (p.right != null && q.left == null) 
            ||  (p.left != null && q.right == null)
            ||  (p.left == null && q.right != null))
                return false;

            if(p.right != null && q.left != null){
                stack1.push(p.right);
                stack2.push(q.left);
            }
            if(p.left != null && q.right != null){
                stack1.push(p.left);
                stack2.push(q.right);
            }            
        }        
        return true;       
    }
    public boolean isSymmetric(TreeNode root) {
        if(root == null)
            return true;
        return leftEqualsRight(root,root);
    }
}

前序遍历入栈的时候必须得对两个节点进行null的判断!否则,第二个例子怎么样都是一样的结果!

都需要对两个节点进行null的判断呀!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值