今日的第二道题,还是树,最近和树gang起来了,好吧目前是我失败的。感觉还是需要系统的看一下树,以及自己敲一遍树的递归和非递归遍历,才能熟悉树的操作过程。上题:
题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
分析:一个树B是另一个树A的子树,则有三种存在的可能:
1、B的根节点和A的根节点一致;
2、B的根节点为A的左子树的某一个节点;
3、B的根节点为A的右子树的某一个节点;
通过递归遍历,判断是否一致,一旦出现不一致的情况,则输出false;
我对这个的理解也不是很好,给出一个不错的解析:
https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/solution/mian-shi-ti-26-shu-de-zi-jie-gou-xian-xu-bian-li-p/
代码:
/**
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) {
if(root1==null||root2==null)return false;
return issame(root1,root2)||HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);
}
public boolean issame(TreeNode tree1,TreeNode tree2){
if(tree2==null)return true;
if(tree1==null||tree1.val!=tree2.val)return false;
return issame(tree1.left,tree2.left)&&issame(tree1.right,tree2.right);
}
}
牛客运行通过
运行时间:20ms
运行内存:9356Kb
题解中还有一种写法,也是想遍历,进行判断
public class Solution {
//遍历大树
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1 == null || root2 == null){
return false;
}
//如果找到与子树相同根的值,走判断方法
if(root1.val == root2.val){
if(judge(root1,root2)){
return true;
}
}
//遍历左孩子,右孩子
return HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);
}
//判断是否是子结构
public boolean judge(TreeNode root, TreeNode subtree) {
//子结构已经循环完毕,代表全部匹配
if(subtree == null){
return true;
}
//大树已经循环完毕,并未成功匹配
if(root == null){
return false;
}
//相等后判断左右孩子
if(root.val == subtree.val){
return judge(root.left, subtree.left) && judge(root.right, subtree.right);
}
return false;
}
}
牛客运行通过
运行时间:19ms
运行内存:9432Kb
第二个方法我比较能看懂,或许稍加思考也是能想到的,但是第一个我是想不到。
上面的代码也是基本按照那个链接来写的,为啥人家这么聪明呢?!!
欢迎各位互相监督交流哦~~