【剑指offer】二叉树的子树

来源:互联网 发布:迅雷影音mac官方下载 编辑:程序博客网 时间:2024/06/08 09:49

代码实现起来主要容易忽略两方面的问题。
第一版:

     public static boolean hasSubTree(TreeNode root1,TreeNode root2){         if(root1==null||root2==null) return false;         if(root1.val!=root2.val){             return hasSubTree(root1.left,root2)||hasSubTree(root1.right,root2);         }else{             boolean hasLeft=true;             if(root2.left!=null){                 hasLeft=hasSubTree(root1.left,root2.left);             }             boolean hasRight=true;             if(root2.right!=null){                 hasRight=hasSubTree(root1.right,root2.right);             }             return true;         }     }

乍一看好像没什么问题,结果不能AC。仔细查看测试用例,发现忽略了root1中多次出现root2的根结点,并且子树出现在第二次或之后的情况。
第二版:

     public static boolean hasSubTree(TreeNode root1,TreeNode root2){         if(root1==null||root2==null) return false;         if(root1.val!=root2.val){             return hasSubTree(root1.left,root2)||hasSubTree(root1.right,root2);         }else{             boolean hasLeft=true;             if(root2.left!=null){                 hasLeft=hasSubTree(root1.left,root2.left);                 if(!hasLeft){                     return hasSubTree(root1.left,root2);                 }             }             boolean hasRight=true;             if(root2.right!=null){                 hasRight=hasSubTree(root1.right,root2.right);                 if(!hasRight){                     return hasSubTree(root2.right,root2);                 }             }             return true;         }     }

结果还是不能AC,原因是这种判断是分解式而不是整体式的。比如root1={8,8,7,9,2},root2={8,9,2}在判断完根结点8之后,接着只会判断root1的左子树中是否含有9而不是左子结点是不是9,那么显然是含有的。继而函数只会判断root1的右子树是否包含2,而不会继续在左子树中搜索是否含有root2,从而给出错误判断。
第三版:
经过两次失败总算明白了,要不判断树是不是另一个树的子树,一定要先知道如何判断树不是另一棵树的直接子树。

     public static boolean hasSubTreeDirectly(TreeNode root1,TreeNode root2){         if(root2==null) return true;         if(root1==null) return false;         if(root1.val!=root2.val) return false;         return hasSubTreeDirectly(root1.left,root2.left)&&hasSubTreeDirectly(root1.right,root2.right);     }

当遇到与root2根结点值相同的结点时,先看此结点是不是直接包含子树root2。如果结点值不相等或者不直接包含子树root2,则分别在其左右子树中继续查找。

     public static boolean hasSubTree(TreeNode root1,TreeNode root2){         if(root1==null||root2==null) return false;         boolean result=false;         if(root1.val==root2.val){             result=hasSubTreeDirectly(root1,root2);         }         if(!result){             result=hasSubTree(root1.left,root2)||hasSubTree(root1.right,root2);         }         return result;     }
0 0
原创粉丝点击