目录

剑指offer-面试题26树的子结构

目录

剑指offer - 面试题26树的子结构

此题核心就是递归。

升级的地方就是两个递归。第一层递归是遍历pRoot1作为根节点。第二层就是对每个访问到的根,判断是否和pRoot2相同(pRoot1包含pRoot2即可,pRoot1可以含有pRoot2没有的节点)。

主要的坑点就是要想明白递归的结束条件。

题目要求pRoot2是pRoot1的子树,在检查是否是子树的递归中,结束条件:pRoot2为空就可以返回true,而不需要pRoot1同时为空。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
	bool checkTreeCorrespond(TreeNode* node1, TreeNode* node2) {
		if (node2 == NULL) { // 一开始条件写成了node1 == NULL && node2 == NULL,导致用例{1,2,3,4,5},{1,2,3}没通过。题目中说空树不是任意一个树的子结构,这个条件只在调用checkTreeCorrespond前判断就行,保证检查的两个根节点都不是空就可以。因为只需要满足node2是node1的子树,所以node1还可以有除了node2之外的子树。这里的递归条件一定要注意,只要遍历到node2是空了,说明当前遍历到的节点都是匹配上了的。
			return true;
		}
		if (node1 == NULL || node2 == NULL) {
			return false;
		}
		if (node1->val == node2->val) {
			return checkTreeCorrespond(node1->left, node2->left) && checkTreeCorrespond(node1->right, node2->right);
		}
		return false;
	}


    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {
		if (pRoot1 == NULL || pRoot2 == NULL) {
			return false;
		}
		if (checkTreeCorrespond(pRoot1, pRoot2)) {
			return true;
		}
		return HasSubtree(pRoot1->left, pRoot2) || HasSubtree(pRoot1->right, pRoot2);
    }
};