树的子结构
解题思路一:递归方式,依次把根节点、做孩子节点、有孩子节点作为根节点递归判断,只要有一个返回为true则就是子结构。判断的过程也是递归的,先判断根节点、左孩子是否一样,再判断右孩子。
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
//如果root1和root2都为空则直接返回false
if (root1==null||root2==null) return false;
//判断是否是子结构
return judeg(root1,root2);
}
public boolean judeg(TreeNode root1,TreeNode root2){
//如果root1和root2都为空则直接返回false
if (root1==null||root2==null) return false;
//先判断根节点
boolean b = isSubtree(root1, root2);
if (!b){
//根节点不是就递归让左孩子为根节点
b = judeg(root1.left, root2);
if (!b){
//根节点和做孩子作为根都不是则递归让有孩子作为根
b = judeg(root1.right, root2);
}
}
//返回判断结果
return b;
}
private boolean isSubtree(TreeNode root1, TreeNode root2) {
//如果root2遍历完了都能对应上,返回true
if (root2==null) return true;
//如果root2遍历完了,root1还没遍历完,返回false
if (root1==null) return false;
//如果有一个节点没有对上返回fasle
if (root1.val!=root2.val) return false;
//如果根节点对上了,则分别去子节点里面匹配
return isSubtree(root1.left,root2.left)&&isSubtree(root1.right,root2.right);
}
解题思路二:字符串比较,第一种方式判断比较麻烦,我们直接把root1和root2转换为字符串进行比较,如果root2是root1的子结构,则root2的字符串一定包含在root1对应的字符串里面。
/**
* 字符串比较的方式
* @param root1
* @param root2
* @return
*/
public boolean HasSubtree2(TreeNode root1,TreeNode root2) {
if(root2 == null || root1 == null){
return false;
}
StringBuffer root1Str = new StringBuffer();
StringBuffer root2Str = new StringBuffer();
visitTree(root1,root1Str);
visitTree(root2,root2Str);
if(root1Str.indexOf(root2Str.toString()) > 0){
return true;
}
return false;
}
/**
* 转化为字符串
* @param root
* @param buffer
*/
private void visitTree(TreeNode root,StringBuffer buffer){
if(root!=null){
buffer.append(root.val);
visitTree(root.left,buffer);
visitTree(root.right,buffer);
}
}