力扣:04.10. 检查子树

112 阅读2分钟

「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

描述

检查子树。你有两棵非常大的二叉树:T1,有几万个节点;T2,有几万个节点。设计一个算法,判断 T2 是否为 T1 的子树。

如果 T1 有这么一个节点 n,其子树与 T2 一模一样,则 T2 为 T1 的子树,也就是说,从节点 n 处把树砍断,得到的树与 T2 完全相同。

注意: 此题相对书上原题略有改动。

  • 示例 1:
 输入:t1 = [1, 2, 3], t2 = [2]
 输出:true
  • 示例 2:
输入:t1 = [1, null, 2, 4], t2 = [3, 2]
输出:false
  • 提示:
  • 树的节点数目范围为[0, 20000]。

解析

有两棵树,要判断B树是否为A树的子树,最直观的办法就是遍历A树的每个结点,去判断以该节点为根结点的树是否与B树相等。

所以,这道题目就被转化成了两个小问题。

  1. 遍历A树。
  2. 判断两颗树是否相同。

遍历A树自然不必多说,无论前序遍历还是中序遍历还是后序遍历都可以达到目标。

而判断两棵树是否相同也非常简单,只需要将两棵树同时进行相同顺序的遍历,如果发现某结点值不同,就说明不相等,如果等到遍历结束,两棵树依旧没有发现不相等的点,就说明这是相同的两棵树。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean checkSubTree(TreeNode t1, TreeNode t2) {
        
        boolean res = false;
        // 如果t2树为null,则必然是t1的子树
        if(t2 == null) {
            return true;
        }
        // 如果t1树为null,并且前面已经判断了t2!=null,则必然t2不是t1的子树
        if(t1 == null) {
            return false;
        }
        // 下面的代码是遍历t1的所有结点
        // 判断当前结点t1与t2是否相同
        if(t1.val == t2.val) {
            // 如果当前点相同,就以其为根节点判断是否为同一棵树
            res = testSubTree(t1,t2);    
        }
        // 无论是当前树还是左子树还是右子树,只要有一个是true,即表示t2是t1的子树
        return checkSubTree(t1.left,t2) || checkSubTree(t1.right,t2) || res;
        
        // 如果相同,则将其与t1进行比对
    }
    // 判断两棵树是否相同,同时遍历即可
    boolean testSubTree(TreeNode t1, TreeNode t2) {
        if(t1 == null && t2 == null) {
            return true;
        }
        if(t1.val != t2.val) {
            return false;
        }
        return testSubTree(t1.left,t2.left) && testSubTree(t1.right,t2.right);
​
    }
}
​

运行结果:

执行结果:通过

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:41.4 MB, 在所有 Java 提交中击败了43.52%的用户