题目
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:
3
/ \
4 5
/ \
1 2
Given tree t:
4
/ \
1 2
Return true, because t has the same structure and node values with a subtree of s.
Example 2:
Given tree s:
3
/ \
4 5
/ \
1 2
/
0
Given tree t:
4
/ \
1 2
Return false.
代码
解法一
利用前序遍历得到该树的顺序排列,空节点使用#代替,把两棵树转换为前序遍历的字符串,比较两个字符串。
/**
* 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) {
String spreorder = genPreOrder(s);
String tpreorder = genPreOrder(t);
return spreorder.contains(tpreorder);
}
public String genPreOrder(TreeNode s) {
StringBuilder sb = new StringBuilder();
Stack<TreeNode> stack = new Stack<>();
stack.push(s);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
if (node == null) {
sb.append(",#");
} else {
sb.append("," + node.val);
}
if (node != null) {
stack.push(node.right);
stack.push(node.left);
}
}
return sb.toString();
}
}
解法二
使用递归遍历,依次判断是否是该树的子树
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
if (s== null && t == null) { return true; }
if (s == null || t == null) { return false; }
if (s.val == t.val) {
return (isSub(s.left, t.left) && isSub(s.right, t.right)) || isSubtree(s.left, t) || isSubtree(s.right, t);
}
return isSubtree(s.left, t) || isSubtree(s.right, t);
}
public boolean isSub(TreeNode s, TreeNode t) {
if (s== null && t == null) { return true; }
if (s == null || t == null) { return false; }
if (s.val != t.val) {
return false;
}
return isSub(s.left, t.left) && isSub(s.right, t.right);
}
}
解法三
学习别人的递归解法,效率比自己写的要高
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
//给定均不为空的二叉树s和t,判定t是否是s的子树
//思路:利用前面是否已经判断过标志位进行递归
return backtrace(s,t,false);
}
public boolean backtrace(TreeNode s,TreeNode t,boolean flag){
//非空判断
if(s==null&&t==null)return true;
if(s==null||t==null) return false;
if(flag&&s.val!=t.val){
//之前节点相等,当前节点不相等,返回false
return false;
}
if(s.val==t.val&&backtrace(s.left,t.left,true)&&backtrace(s.right,t.right,true)){
return true;
}else{
//节点不相等,flag置为false,递归判断左右子树
return backtrace(s.left,t,false)||backtrace(s.right,t,false);
}
}
}
java