我在写java代码的时候,因为一个小错,查了两个多小时也没查出来,后来硬对比出来的:
if(root2 == null){
return true;
}
if(root1 == null){
return false;
}
在判断是否是子树(函数isthisSubtree)的时候,root2为空的情况要写在第一个,不然牛客网的第一个例子都过不去;
我想了一下,可能是因为子结构root2的点比较少,会先root1一步走完;但是应该不是这个原因,比如没有子结构的情况,随着遍历的深入,root1上的点会越来越少,而root2上的点是不会动的;
因此应该是考虑到只要root2为null,那么它一定是树的子结构这个硬性条件才把它放到第一位;
而root1=null的情况实际上是两种情况产生,1.直接就是null,那么此时,root2只要非空我们就返回false,2:root2不是root1的子结构,随着遍历的深入,root1变为null,此时return false;所以root1 = null 不能直接放在开头,它可能返回true;
作为链表外的另一个递归代表,树的结构简直是为递归而生,当我们要判断子结构时,要注意的无非就是:
子树的子树仍然是树的子树;
那么我们可以从根节点开始判断,根节点的值一样,就判断左节点和右节点,只有左右节点的值都一样时返回true,以此类推,直到遍历完子树,只要有一个节点不一样,就返回false
Python代码
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def HasSubtree(self, pRoot1, pRoot2):
# write code here
res = False
if(pRoot1 != None) &(pRoot2 != None):
if(pRoot1.val == pRoot2.val):
res = self.isthisSubtree(pRoot1,pRoot2)
if(res == False):
res = self.HasSubtree(pRoot1.left,pRoot2)|self.HasSubtree(pRoot1.right,pRoot2)
return res
def isthisSubtree(self,pRoot1,pRoot2):
if pRoot2 == None:
return True
if pRoot1 == None:
return False
if pRoot1.val != pRoot2.val:
return False
return self.isthisSubtree(pRoot1.left,pRoot2.left)&self.isthisSubtree(pRoot1.right,pRoot2.right)
java代码
/**
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 res = false;
if(root1!=null&root2!=null){
if(root1.val == root2.val){
res = this.isthisSubtree(root1,root2);}
if(!res){
res = this.HasSubtree(root1.left,root2);
}
if(!res){
res = this.HasSubtree(root1.right,root2);
}
}return res;
}
public boolean isthisSubtree(TreeNode root1,TreeNode root2){
if(root2 == null){
return true;
}
if(root1 == null){
return false;
}
if(root1.val != root2.val){
return false;
}
return this.isthisSubtree(root1.left,root2.left) && this.isthisSubtree(root1.right,root2.right);
}
}