当前位置:首页 > 牛客 > 牛客3732题解:递归分治判断二叉树子树关系

牛客3732题解:递归分治判断二叉树子树关系

4个月前 (08-07)

牛客3732题解:递归分治判断二叉树子树关系 牛客题解 二叉树 递归 分治算法 树结构 C++ 第1张

一、题目解读

牛客3732题要求判断二叉树A是否包含二叉B作为子树。即是否存在A的某子树与B结构完全相同(节点值、左右子树关系均匹配)。问题核心在于高效搜索A的所有子树并与B进行比对,需避免重复遍历。

二、解题思路

核心思想为:

1. 递归分治:将大问题拆解为小问题,分别判断A的根节点是否等于B的根节点,若相等则递归检查左右子树;

2. 子树匹配:设计isSame函数判断两树是否完全相同,通过递归遍历左右子树并比对节点值;

3. 三种可能性:若A的根节点匹配B,或A的左/右子树包含B,则返回true。

三、解题步骤

1. 主函数HasSubtree:

    输入校验:若A或B为空,直接返回false;

    递归判断三种情况:

        以A为根节点的子树是否与B相同(调用isSame);

        A的左子树是否包含B;

        A的右子树是否包含B。

2. 辅助函数isSame:

    若B为空,说明B已匹配完成,返回true;

    若A为空但B不空,匹配失败;

    若节点值不相等,失败;

    递归检查A的左右子树是否与B的左右子树匹配。

四、代码与注释

class Solution {
private:
    bool isSame(TreeNode* A, TreeNode* B) {
        // B为空表示B树已经匹配完成
        if (B == nullptr) return true;
        // A为空但B不为空,匹配失败
        if (A == nullptr) return false;
        // 当前节点值不相等,匹配失败
        if (A->val!= B->val) return false;
        // 递归检查左右子树
        return isSame(A->left, B->left) && isSame(A->right, B->right);
    }
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {
        if (pRoot1 == nullptr || pRoot2 == nullptr) return false;
        // 三种情况满足一种即可:
        // 1. 以pRoot1为根节点的子树包含pRoot2
        // 2. pRoot2在pRoot1的左子树中
        // 3. pRoot2在右子树中
        return isSame(pRoot1, pRoot2) || HasSubtree(pRoot1->left, pRoot2) ||
               HasSubtree(pRoot1->right, pRoot2);
    }
};

五、总结

本解法通过递归分治将子树匹配问题分解为局部节点比对,时间复杂度O(nm)(n、m为两树节点数),空间复杂度O(n+m)(递归)。关键在于设计清晰的递归逻辑与边界条件,适用于需要判断树包含关系的场景,体现了递归算法的优雅与高效。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣LCR182:字符串操作三连 从基础拼接到底层指针优化

力扣LCR182:字符串操作三连 从基础拼接到底层指针优化

题目重解需要将密码字符串从第target个字符开始进行重新排列,形成新的动态密码。例如输入"password"和target=3,结果应为"swordpas"。...

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

力扣第654题:最大二叉树解题教程 用数组构造最大二叉树

题目解读给定一个不含重复元素的整数数组,我们需要构建一棵最大二叉树。构建规则是:数组中的最大值作为根节点,其左侧子数组构建左子树,右侧子数组构建右子树,然后递归地应用这个规则。这种构建方式体现了分治思...

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

题目重解想象你是一名药师,有t分钟在山上采集m种草药。每种草药需要time分钟采集,价值为num。这就像考试时分配时间做题,要选择收益最大的题目组合。题目要求计算在规定时间内能获得的最大草药价值。解题...

力扣933题:队列的妙用:如何高效统计最近请求

力扣933题:队列的妙用:如何高效统计最近请求

题目重解:我们需要设计一个能统计最近3000毫秒内请求次数的系统。每当新的请求到来时,它会带有时间戳t,我们需要返回过去3000毫秒内(包括当前)发生的请求总数。这就像是在时间轴上维护一个滑动窗口,只...

力扣第44题:寻找两个正序数组的中位数 - 合并排序解法详解

力扣第44题:寻找两个正序数组的中位数 - 合并排序解法详解

内容简介本文详细解析了力扣第44题"寻找两个正序数组的中位数"的合并排序解法。通过双指针技术合并两个有序数组,然后直接计算合并后数组的中位数。虽然时间复杂度为O(m+n),但这种方...

牛客NC67题解:汉诺塔递归算法与解题步骤

牛客NC67题解:汉诺塔递归算法与解题步骤

一、题目解读牛客NC67题要求解决汉诺塔问题,这是一个经典的递归算法题目。题目给定整数n,代表汉诺塔中的盘子数量,需要输出将n个盘子从起始柱移动到目标柱的所有步骤。汉诺塔问题规则为:每次只能移动一个盘...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。