牛客3732题:二叉树子结构的判断
一、问题背景与定义
在二叉树相关算法中,判断一棵树是否是另一棵树的子结构是一个常见且实用的问题。根据题目定义,我们需要判断树B是否是树A的子结构,其中空树不被认为是任何树的子结构。
子结构的定义:树B是树A的子结构,意味着在树A中存在某个节点,以该节点为根的子树与树B在结构和节点值上完全一致。注意这与"子树"概念有所不同,子结构不要求必须从叶子节点开始匹配。
二、算法思路解析
解决这个问题可以采用递归解法:
主函数HasSubtree:
当前pRoot1节点开始的子树是否匹配pRoot2
pRoot2是否在pRoot1的左子树中
pRoot2是否在pRoot1的右子树中
处理边界条件:如果pRoot1或pRoot2为空树,直接返回false
检查三种可能性:
这三种情况满足任意一种即可返回true
辅助函数isSame:
B为空:表示B已经匹配完成
A为空但B不为空:匹配失败
节点值不相等:匹配失败
递归判断两棵树是否相同
递归终止条件:
递归检查左右子树是否都匹配
三、完整代码与注释
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { private: /** * 判断两棵树是否相同(递归实现) * @param A 树A的节点 * @param B 树B的节点 * @return bool 是否相同 */ 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); } };
四、边界情况处理
空树处理:题目明确空树不是任何树的子结构
单节点树:B只有一个节点时,只需在A中找到值相同的节点
重复值节点:当A中有多个节点值与B根节点相同时,需要逐一检查
部分匹配:B是A中某条路径的一部分但不是完整子树
原创内容 转载请注明出处