A tree T2 is a subtree of T1 if there exists a node n in T1 such that the subtree of n is identical to T2. That is, if you cut off the tree at node n, the two trees would be identical.
Copy 1 3
/ \ /
T1 = 2 3 T2 = 4
/
4
Copy 1 3
/ \ \
T1 = 2 3 T2 = 4
/
4
这题来自ctci 4.10。如果两棵树都不大的话,我们可以通过判断T2的preorder+null是否T1的perorder+null序列的子序列来判断是否subtree。会花费O(n + m)的空间和时间。但如果T1非常大的话,我们可以先从T1里找T2root的值,找到了再判断是否subtree。这个方法会花O(logn + logm)的空间,平均时间是O(n + km),k是T1里T2root值的个数。worse case时间会变成O(nm)。
Copy public boolean isSubtree( TreeNode T1 , TreeNode T2) { // ---27ms
if (T1 == null && T2 != null ) {
return false ;
} else if (T2 == null ) {
return true ;
}
boolean found = false ;
if ( T1 . val == T2 . val ) {
found = same(T1 , T2) ;
}
if (found) {
return true ;
} else {
return isSubtree( T1 . left , T2) || isSubtree( T1 . right , T2) ;
}
}
private boolean same( TreeNode n1 , TreeNode n2) {
if (n1 == null && n2 == null ) {
return true ;
} else if (n1 == null && n2 != null ) {
return false ;
} else if (n1 != null && n2 == null ) {
return false ;
}
if ( n1 . val != n2 . val ) {
return false ;
}
return same( n1 . left , n2 . left ) && same( n1 . right , n2 . right ) ;
}
//-------用遍历好像比递归快,16ms
public boolean isSubtree( TreeNode s , TreeNode t) {
if (s == null && t != null ) {
return false ;
} else if (t == null ) {
return true ;
}
Stack < TreeNode > stack = new Stack <>();
stack . push (s);
while ( ! stack . isEmpty ()) {
TreeNode cur = stack . pop ();
if ( cur . val == t . val ) {
if ( isSame(cur , t) ) {
return true ;
}
}
if ( cur . right != null ) {
stack . push ( cur . right );
}
if ( cur . left != null ) {
stack . push ( cur . left );
}
}
return false ;
}
private boolean isSame( TreeNode s , TreeNode t) {
if (s == null && t == null ) {
return true ;
} else if (s == null || t == null ) {
return false ;
}
if ( s . val != t . val ) {
return false ;
}
boolean left = isSame( s . left , t . left ) ;
boolean right = isSame( s . right , t . right ) ;
return left && right;
}