Description
Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself.
Example 1:
Given tree s:
Given tree t:
Return true, because t has the same structure and node values with a subtree of s.
Example 2:
Given tree s:
Given tree t:
Return false.
Solution
DFS
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
if (s == null || t == null) {
return false;
}
return isSameTree(s, t) || isSubtree(s.left, t)
|| isSubtree(s.right, t);
}
public boolean isSameTree(TreeNode s, TreeNode t) {
if (s == null && t == null) {
return true;
}
if (s == null || t == null) {
return false;
}
return s.val == t.val && isSameTree(s.left, t.left)
&& isSameTree(s.right, t.right);
}
}
Preorder with flag, time O(n), space O(n)
可以采用序列化树的方式将每棵树转换成一个String,然后判断是否是substring即可。
我的想法最初也是通过遍历的方法看两个树的遍历结果是否一致。那么我想只有通过前序遍历和中序遍历两个遍历才能确定结果,但是看了大神的想法之后发现自己想的太复杂,而且存在问题。
问题是可能存在不同的数字相同的遍历结果。
大神的方法是在当节点为空的时候给一个“#”表示
,这样就能表示出不同的子树,因此只需要遍历一次就能得到结果。每次遍历到树的结尾的时候能够按照#区分,另外每个树的节点值之间用”,”分割
。
在提交的时候又遇到一个问题,就是12和2的结果是一样的,那么我在每个遍历结果的开头位置再加上一个逗号就完美解决了
。
另外注意,不要判断左右子树不为空再去遍历树,这样就不能添加上“#”了。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
StringBuilder spreorder = new StringBuilder();
StringBuilder tpreorder = new StringBuilder();
preorder(s, spreorder.append(','));
preorder(t, tpreorder.append(','));
return spreorder.toString().contains(tpreorder.toString());
}
public void preorder(TreeNode root, StringBuilder sb) {
if (root == null) {
sb.append("#,");
return;
}
sb.append(root.val).append(',');
preorder(root.left, sb);
preorder(root.right, sb);
}
}