二叉树 四步走模板 解决一切二叉树对称问题

这篇博客详细介绍了如何使用四步走模板解决各种二叉树对称性问题,包括判断两棵树是否相同、是否对称、是否为另一棵树的子树。文章通过具体的例子和代码解释了四步法的运用,强调了递归和节点值比较的重要性,并提供了相关题目链接以供练习。
摘要由CSDN通过智能技术生成

题目:相同的树

原题链接

给定两个二叉树,编写一个函数来检验它们是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

在这里插入图片描述

四步走模板

四步走模板主要用于判断两个节点是否是相同的,下面的逻辑关系是层层递进的

  • 如果两个节点都是空的,返回true
  • 不满足之前的所有条件,并且两个节点中一个为空,返回false
  • 不满足之前的所有条件,并且两个节点的值不等,返回false
  • 不满足之前的所有条件,说明两个节点的值相等,继续递归子树

下面算是四步法的经典代码了

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        // 四步走
        // 如果都为空,说明满足条件
        if(p==null && q==null) return true;
        // 如果只有一方为空,不满足条件
        if(p==null || q==null) return false;
        // s和 t此时都不为空,如果不相等,则不满足条件
        if(p.val != q.val) return false;
        // 继续递归两个的左子树是否相同和右子树是否相同
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}

题目:对称的二叉树

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

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
在这里插入图片描述
对于这种二叉树的对称问题,也是套四步法的模板,不过最后递归的时候递归的是左子树的左子树右子树的右子树比较

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root == null) return true;
        return helper(root.left, root.right);
    }

    // 帮助方法四步走
    boolean helper(TreeNode left, TreeNode right){
        if(left == null && right == null){
            return true;
        }
        if(left == null || right == null){
            return false;
        }
        if(left.val != right.val){
            return false;
        }
        // 这一步的条件有所调整
        return helper(left.left, right.right) && helper(left.right, right.left);
        // 相同的树,是这么写的
		// return isSameTree(left.left, right.left) && isSameTree(left.right, right.right);
    }
}

一开始这题竟然提交没通过,检查了才知道原来自己的返回值不匹配。
if(root == null) return true 如果根节点为空(即一颗空的二叉树),它也是对称的,而且需要返回true。不能直接返回 null

题目:另一个树的子树

原题链接

给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

示例 1:
给定的树 s:

     3
    / \
   4   5
  / \
 1   2

给定的树 t:

   4 
  / \
 1   2

返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。

四步法 + 双递归解法

树 s中的每一个节点都有可能成为子树的起点,所以需要递归树 s的每个节点

class Solution {
    public boolean isSubtree(TreeNode s, TreeNode t) {
    	// 这里使用到了双递归
    	if(s==null) 
    		return false;
    	// 只要当前节点或者左右子树中有一个 满足是另一个子树的起点就好了,所以三个 "||"
    	return helper(s, t)||isSubtree(s.left, t)||isSubtree(s.right, t);
    		
    }

    public boolean helper(TreeNode s, TreeNode t){
        // 四步走
        if(s == null && t == null){
            return true;
        }
        if(s == null || t == null){
            return false;
        }
        if(s.val != t.val){
            return false;
        }
        return helper(s.left, t.left)&&helper(s.right, t.right);
    }
}

题目:树的子结构

原题链接

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

题目分析
这里与上一个题(另一个树的子树)比较类似,也是可以用 四步法+双递归

不过需要注意概念上的差别,子树是从某个节点开始,之后的所有节点都和父节点相同。子结构则是,它有的结构,父树中都有,而父树中有的结构它不一定有,上图:
在这里插入图片描述在这里插入图片描述
上面右边那棵树是左边树的子结构(虽然没有3和11),结构却基本相同。但是右边树不是左边树的子树(子树的要求挺高)

所以 四步法的需要做一点点调整,即 B的子树中如果有空节点,而A中的该位置不为空,并不影响B是A的子结构。

解题代码

class Solution {
    public boolean isSubStructure(TreeNode A, TreeNode B) {
        return (A==null || B == null) ? false : helper(A,B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
    }


    boolean helper(TreeNode left, TreeNode right){
    	// 只用子结构没有这个节点,那么树有没有不重要,返回true
        if(right == null) return true;
        // if(left==null && right==null) return true; //两个树都是空
        
        // 如果子结构有的,树没有,则false
        if(left == null) return false;
		// if(left==null || right==null) return false; //有一个树不为空

        if(left.val != right.val) return false;
        return helper(left.left, right.left) && helper(left.right, right.right);
    }
}

后记

看到最后了的话,可以访问我的CSDN博客主页。

搜索关键字“模板”,看到更多刷题模板!!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值