题目难度:简单
一、题目描述
给你两棵二叉树 root
和 subRoot
。检验 root
中是否包含和 subRoot
具有相同结构和节点值的子树。如果存在,返回 true
;否则,返回 false
。
二叉树 tree
的一棵子树包括 tree
的某个节点和这个节点的所有后代节点。tree
也可以看做它自身的一棵子树。
LeetCode链接:572. 另一棵树的子树 - 力扣(LeetCode)
二、解题思路
如果一个树是另一个树的子树,则
- 要么这两个树相等
- 要么这个树是另一个树左树的子树
- 要么这个树是另一个树右树的子树
核心思路:
- 写两个函数:
- 主函数:依次递归遍历完root,拿到「每个子树(当前树)的根」
- 子函数:判断它与subRoot是否是同一颗树
递归过程演示:
依次前序遍历完「当前树(1、2、3、4、5)的根节点」,分别跟subRoot比较
![]()
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
// 判断root中的当前树和subRoot是否相同(判断两颗树是否相同的函数)
bool isSameTree(struct TreeNode* root, struct TreeNode* subRoot)
{
// 先判断传进来的两颗树的根节点
// 都为空,说明相同,返回true
if(root == NULL && subRoot == NULL)
{
return true;
}
// 一个为空一个不为空,说明不相同,返回false
if(root == NULL || subRoot == NULL)
{
return false;
}
// 都不为空,但节点值不相同,说明不相同,返回false
if(root->val != subRoot->val)
{
return false;
}
// 经过前面if的判断,既然运行到这里来了,说明两颗树的根节点相同
// 则继续往下递归遍历,判断两颗树的左右子树的根节点是否都相同
return _isSameTree(root->left, subRoot->left)
&& _isSameTree(root->right, subRoot->right);
}
// 递归遍历完(前中后序都可以)root中的所有子树(当前树),
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
if(root == NULL)
{
return false;
}
// 1. 判断root中的当前树和subRoot是否相同
if(isSameTree(root, subRoot))
{
return true; // 相同则返回true
}
// 2. 不相同,则继续往下遍历root左右子树的根
// 如果左子树中有相同的,就不用去遍历右子树了,所以是或||
return isSubtree(root->left, subRoot)
|| isSubtree(root->right, subRoot);
}
附:LeetCode评论区中某个大佬写的题解
// 判断两树是否相同
bool isSametree(struct TreeNode* s, struct TreeNode* t)
{
if (s == NULL && t == NULL) return true;
return s && t
&& s->val == t->val
&& isSametree(s->left, t->left)
&& isSametree(s->right, t->right);
}
// 递归遍历完s树
bool isSubtree(struct TreeNode* s, struct TreeNode* t) {
if (s == NULL && t == NULL) return true;
if (s == NULL && t != NULL) return false;
return isSametree(s, t)
|| isSubtree(s->left, t)
|| isSubtree(s->right, t);
}