另一颗树的子树

给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

在这里插入图片描述
在这里插入图片描述
解题思路:
先从跟结点开始,看两颗树的根节点是否相同,然后递归遍历两棵树的左右子树,如果都相同返回true;否则让树s左右子树分别和树t进行递归遍历,如果s树递归结束发现没有和树t相同的树则返回false。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool _isSubtree(struct TreeNode* s, struct TreeNode* t){
    if(s == NULL && t == NULL)
        return true;
    else if(s == NULL && t != NULL)
        return false;
    else if(s != NULL && t == NULL)
        return false;
    else if(s->val != t->val)
        return  false;
    return _isSubtree(s->left,t->left) && _isSubtree(s->right,t->right);
}

bool isSubtree(struct TreeNode* s, struct TreeNode* t){
    if(s == NULL)
        return false;
    
    if(_isSubtree(s,t))
    {
        return true;
    }
    bool left = isSubtree(s->left,t);
    bool right = isSubtree(s->right,t);

    return left || right;
}
### 关于二叉是否为一棵树子树的算法实现 判断一棵二叉是否是一棵二叉子树是一个经典的递归问题。该问题的核心在于通过递归比较两棵的部分结构来验证它们的关系。 #### 方法概述 为了完成这一任务,通常会设计两个辅助函数: 1. **`isSameTree`**: 用于判断两棵是否完全相同。 2. **`isSubtree`**: 用于遍历主中的每一个节点,并将其作为潜在的根节点与目标子树进行匹配。 以下是具体的实现方式: --- #### C语言实现 ```c /** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */ bool isSameTree(struct TreeNode* p, struct TreeNode* q) { if (p == NULL && q == NULL) return true; // 若两者都为空,则相同 if (p == NULL || q == NULL) return false; // 若其中一个为空而一个不为空,则不同 if (p->val != q->val) return false; // 值不同的情况返回false return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); // 继续递归检查左右子树 } bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){ if (root == NULL) return false; // 主为空则不可能存在子树关系 if (isSameTree(root, subRoot)) return true; // 当前节点满足条件时直接返回true return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot); // 向下递归寻找可能的匹配位置 } ``` 此代码实现了基本逻辑:先利用 `isSameTree` 函数逐层对比两棵的对应部分,再借助 `isSubtree` 遍历整棵以找到合适的起始点[^1]。 --- #### Java实现 ```java public class Solution { public boolean isSubtree(TreeNode s, TreeNode t) { if (s == null) return false; // 如果主已经遍历完毕仍未发现匹配项,则返回false if (isSame(s, t)) return true; // 发现有相同的子树即刻返回true return isSubtree(s.left, t) || isSubtree(s.right, t); // 对左右分支分别尝试匹配 } private boolean isSame(TreeNode s, TreeNode t) { if (s == null && t == null) return true; // 二者均无后续节点视为一致 if (s == null || t == null) return false; // 单侧有剩余节点说明无法构成子树 if (s.val != t.val) return false; // 节点值不符立即退出 return isSame(s.left, t.left) && isSame(s.right, t.right); // 进一步深入检测左右孩子结点的一致性 } } ``` 这段Java版本同样遵循了双层次递归的设计思路,在效率和可读性之间取得了平衡[^3]。 --- #### 时间复杂度分析 对于大小分别为 \(m\) 和 \(n\) 的两棵来说,最坏情况下需要对每一对组合执行一次完整的形结构比对操作,因此总体时间开销大致可以估计为 O(m \times n)[^2]。 尽管如此,实际运行过程中由于提前终止机制的存在(一旦确认某处不符合即可跳过其余无关计算),平均表现往往优于理论上限。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值