二叉树15:对称的二叉树

题目:请实现一个函数,用来判断一棵二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。


思路:何为对称树,所谓对称是指以根结点为界的左右子树左右对称。

方法一:思路很简单,对于先序遍历或者中序遍历或者后序遍历,例如先序遍历(中-左-右),再写一个对称的先序遍历算法(中-右-左)然后分别遍历二叉树,将其放入到2个集合中,然后进行逐一比较即可。需要注意的是,对于二叉树上为null的结点也要遍历并放入到集合中,否则有可能数值相同但是不对称的情况(当所有结点的值相同时)。这种方法很简单,但是需要遍历所有的结点,即使一开始的结点就不对称也需要遍历全部全部的结点,效率较低,需要改进。

方法二:要判断二叉树root是否对称,就看其左右子树root.left和root.right之间是否对称。首先left和right结点的val要相同②,否则不对称;然后left的左子树③要与right的右子树③对称,并且left的右子树④要与right的左子树④对称;于是问题转化为left的左子树③要与right的右子树③对称,并且left的右子树④要与right的左子树④对称。而要判断left的左子树③与right的右子树③是否对称与初始的问题:判断left子树②与right子树②是否对称是相同的原理。即问题总是判断2棵子树是否对称:而要判断2棵子树是否对称的逻辑都是一样的,就是判断这2个子树的根结点值是否相同&&left的左子树与right的右子树是否相同&&left的右子树与right的左子树是否相同。即给定2棵树就可以判断其是否对称,不需要管这2棵树是否是相连于同一个结点(例如结点②和结点②都相连于①)或者是相互远离的(例如结点③和结点③相互远离)。显然判断一棵树是否对称即判断它的2棵子树是否对称,而判断2棵子树left和right是否对称依赖于判断left.left和right.right是否对称并且left.right和right.left是否对称。设计一个递归方法,该方法用于输入2个树的根结点,然后判断这2棵树是否对称并返回true和false.

递推关系:if(process(left.left,right.right)==true&&process(left.right,right.left)==true){returntrue;}

边界条件:

if(left==null&&right!=null)returnfalse;

if(right==null&&left!=null)returnfalse;

if(left==null&&right==null)returntrue;

if(left.val!=right.val)returnfalse;

这个递归非常巧妙,并不是基于后序遍历的改造而是一个全新的逻辑,但是都是利用了初始条件+递推关系的方式来解决问题,对于递归,需要多看多理解多练习多感悟。//判断一棵树是否对称:即判断2棵子树是否对称,递归:判断2组共4棵树是否对称 .

巧妙:
public class Solution {
    boolean isSymmetrical(TreeNode pRoot){
        //特殊输入
        if(pRoot==null) return true;
        //调用方法解决问题
        return this.process(pRoot.left,pRoot.right);
    }
    
    //建立一个递归的方法:输入一个根结点,判断这棵子树是否对称
    private boolean process(TreeNode leftTree,TreeNode rightTree){
        //边界条件
        if(leftTree==null) return rightTree==null;
        if(rightTree==null) return leftTree==null;
        
        //如果2子树不为null,那么先看值是否相同
        if(leftTree.val!=rightTree.val) return false;
        
      //此时2个子树的值相同,判断这2棵树是否对称依赖于判断它的4棵子树是否满足2组对称条件
        boolean res1=process(leftTree.left,rightTree.right);
        boolean res2=process(leftTree.right,rightTree.left);
        return res1&&res2;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值