题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)jia
思路:首先判断是否为空树,如果为空,则返回false,否则先序遍历pRoot1这棵树,如果所指结点与pRoot2根节点的值相等,则依次比较其每一个结点,需要注意的地方是,情况较多,需要考虑pRoot1为空但是pRoot2不空的时候,返回false等。
由于对递归的使用不够熟练,所以代码实现较为繁琐:
class Solution { public: bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) { if(pRoot2 == NULL||pRoot1==NULL) return false; else{ bool result = false; preOrder(pRoot1,pRoot2,pRoot2,result); if(result) return true; else return false; } } void compare(TreeNode* pRoot1, TreeNode* pRoot2,bool &flag){ //一种特殊情况,当pRoot1为空但是pRoot2不空的时候,返回false if(!pRoot1&&pRoot2){ flag = false; } //当flag=false的时候无需再继续比较 if(pRoot1&&pRoot2&&flag){ if(pRoot1->val == pRoot2->val){ flag = true; } else{ flag = false; } //递归比较其左右子树 compare(pRoot1->left, pRoot2->left,flag); compare(pRoot1->right, pRoot2->right,flag); } } void preOrder(TreeNode* pRoot1, TreeNode* pRoot2,TreeNode* pRootHead2,bool &flag){ //将根节点与pRoot2进行比较 if(pRoot1 && pRoot2 && !flag){ if(pRoot1->val == pRoot2->val){ flag = true; compare(pRoot1,pRoot2,flag);//存在相等结点,则去比较子树 if(!flag){ pRoot2 = pRootHead2; //让pRoot2继续指向子树根节点 flag = false; } } //先序遍历左子树 preOrder(pRoot1->left,pRoot2,pRootHead2,flag); //先序遍历右子树 preOrder(pRoot1->right,pRoot2,pRootHead2,flag); } } };
错误思路:先序遍历两个树,然后利用KMP算法计算是否存在子序列。如下图示,满足题意,但是先序遍历序列不满足。
剑指offer上的答案:
首先该题目可以分为两部分:第一步在树A中找到和B根节点一样的结点R,第二步,判断树A中以结点R为根节点的字数是不是包含树B一样的结构。
第一步在树A中查找与根节点值一样的结点,其实就是树的遍历,
public boolean HasSubtree(TreeNode root1,TreeNode root2) { if(root1 == null || root2 == null){ return false; } boolean result = false; if(root1.val == root2.val){ result = isSubtree(root1,root2); } if(!result){ result = HasSubtree(root1.left,root2); } if(!result){ result = HasSubtree(root1.right,root2); } return result; }
第二步是判断树A中以R为根节点的子树是不是和树B具有相同的结构。同样适用递归的思想,如果结点R的值和树B的根节点的值不相同,则肯定返回false,或者是达到树A或者树B的叶节点,如果到达树B的叶节点,则返回true,如果树A到达叶节点但是树B没有到达叶节点则返回false。
public boolean isSubtree(TreeNode root1,TreeNode root2){ if(root2 == null) return true; if(root1 == null) return false; if(root1.val != root2.val) return false; return isSubtree(root1.left,root2.left)&&isSubtree(root1.right,root2.right); }