题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路:
在树A中寻找树B的跟节点,
(1)如果没找到,直接返回false。
(2)如果找到了,则继续比较左子节点和右子节点的值是否相同。如果不同,则说明B不是A的子树,此时继续往下寻找,寻找下一个A中和B跟节点相同的点,并比较两个树对应的左右子节点。
比如下图中最先匹配到了A,B相同的根节点1,但是在比较左右子节点的值的时候发现是不相等的,此时,应该继续向下寻找下一个相同根节点,左边1,3,4中的1,再和B进行比较。
考虑的点:
首先,寻找相同根节点时,
(1)如果两个树均为空,则直接返回false;
(2)任意一棵树为空,返回false。
(3)两棵树都不为空,
①若A,B的根节点值相等,则再继续判断根节点之外的子结构。
②若A,B的根节点不等,则用树A的左子节点继续和B的根节点做匹配。
③若A的根节点和左子节点都和B的根节点不等,则继续用A的右子节点和B的根节点做匹配。
其次,再寻找到根节点之后,我们就需要判断两个tree的左右子节点是否匹配,在判断的过程中,
(1)如果tree1为空,但是tree2不为空,直接返回false。此时小树tree1并不能包含tree2这棵子树。
(2)如果tree1不为空,tree2为空,说明tree2已经匹配完毕,(此时前面的节点都是匹配成功的),返回true.
(3)匹配过程中,tree1的节点值和tree2的节点值不相等,则返回false。
综上分析,递归的截止条件:
(1)如果B是一个空树,则递归截止。
(2)如果被遍历的树A是空树,则递归截止。
(3)如果遍历到了B的尾节点,则递归截止。
(4)A树从头到尾遍历完了,始终没有和B相同的节点,递归截止。
实现:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
boolean result=false;
if(root1!=null&&root2!=null){
if(root1.val==root2.val){
result=DoseTree1HaveTree2(root1,root2);
}
if(!result){
result=DoseTree1HaveTree2(root1.left,root2);
}
if(!result){
result=DoseTree1HaveTree2(root1.right,root2);
}
}
return result;
}
private boolean DoseTree1HaveTree2(TreeNode tree1,TreeNode tree2){
if(tree1==null&&tree2!=null){
return false;
}
if(tree2==null){
return true;
}
if(tree1.val!=tree2.val){
return false;
}
return DoseTree1HaveTree2(tree1.left,tree2.left)&&DoseTree1HaveTree2(tree1.right,tree2.right);
}
}
参考博客: