【LeetCode】每日一题 面试题 04.10. 检查子树

163 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情

[面试题 04.10. 检查子树](leetcode.cn/problems/ma…)

检查子树。你有两棵非常大的二叉树: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]

解题思路

// 第一种
先写一个判断两个树是否相等的函数,用递归去判断两个树的val子树是否相等
​
有了判断两棵树是否相等的函数后,用该函数递归去判断t1或者t1的子树和t2是否相等
​

代码实现

// 第一种
/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} t1
 * @param {TreeNode} t2
 * @return {boolean}
 */
var checkSubTree = function(t1, t2) {
​
    function isSame(t1, t2) {
        if (!t1 && !t2) return true
        if (t1 && t2) {
            return t1.val === t2.val && isSame(t1.left, t2.left) && isSame(t1.right, t2.right)
        }
        return false
    }
​
    if (isSame(t1, t2)) return true
    if (!t1) return false
    return checkSubTree(t1.left, t2) || checkSubTree(t1.right, t2)
};
​
// 第二种
var checkSubTree = function(t1, t2) {
    let list = [t1];
    // 层次遍历
    while(list.length){
        // 先进先出
        let temp = list.shift();
        if(temp.val === t2.val && checkEqual(temp, t2)) return true;
        if(temp.left) list.push(temp.left);
        if(temp.right) list.push(temp.right);
    }
    return false;
};
// 判断两棵树是否‘相等’
const checkEqual = (node1, node2) => {
    if(node1 === null && node2 === null) return true;
    if(node1 === null || node2 === null) return false;
    if(node1.val !== node2.val) return false;
    return checkEqual(node1.left, node2.left) && checkEqual(node1.right, node2.right);
}
​
// 第三种
/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} t1
 * @param {TreeNode} t2
 * @return {boolean}
 */
var checkSubTree = function(t1, t2) {
   // 判断是否是子树===>子树节点跟树一样===>一路递归对比,一直到t2为null,相等我们会才一起继续走
   if(!t2){
       return true
   }
   if(!t1){
       return false
   }
   // 其实这步就是前(先)序遍历
   if(t1.val===t2.val){
       return checkSubTree(t1.left,t2.left)&&checkSubTree(t1.right,t2.right)
   } else{
       // 先找到目标子树的根节点
       return checkSubTree(t1.left,t2)|| checkSubTree(t1.right,t2)
   }
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;