持续创作,加速成长!这是我参与「掘金日新计划 · 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)
}
};
如果你对这道题目还有疑问的话,可以在评论区进行留言;