问题描述
给定两棵二叉树 root 和 subRoot,我们需要判断 root 中是否包含一棵和 subRoot 具有相同结构和节点值的子树。如果存在这样的子树,返回 true;否则返回 false。
解决思路
这个问题的关键在于理解"子树"的定义:一棵子树包括某个节点和这个节点的所有后代节点。基于这个定义,我采用了"先找相同节点,再比较子树结构"的两步策略。
核心思想
-
相同树判断:首先实现一个辅助函数来判断两棵树是否完全相同
-
子树搜索:在主函数中递归搜索与子树根节点值相同的节点,然后进行相同树判断
代码实现
// 判断两棵树是否完全相同
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
if(p==NULL || q==NULL) // 两者有一者为空比较返回结果
return p==q;
if(p->val != q->val) return false; // 值不同返回
bool left=isSameTree(p->left,q->left);
if(left==false) return false; // 左树不同直接返回
bool right=isSameTree(p->right,q->right);
return left && right;
}
// 判断subRoot是否是root的子树
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
if(root==NULL) return false; // 匹配不到返回false
// 结点值相同时进入相同树匹配
if(root->val==subRoot->val && isSameTree(root,subRoot))
return true;
// 递归匹配左右子树
return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}
算法分析
isSameTree 函数
-
时间复杂度:O(min(m,n)),其中m和n分别是两棵树的节点数
-
空间复杂度:O(min(m,n)),递归调用栈的深度
isSubtree 函数
-
时间复杂度:O(m×n),最坏情况下需要比较root树中的每个节点
-
空间复杂度:O(max(m,n)),递归调用栈的深度
关键点说明
-
递归终止条件:当遇到空节点时,通过
p==q来同时处理各种空节点情况 -
提前返回优化:在
isSameTree中,一旦发现左子树不匹配就立即返回,避免不必要的右子树比较 -
短路求值:在
isSubtree中使用||运算符,左子树匹配成功时不再检查右子树
5万+

被折叠的 条评论
为什么被折叠?



