体验算法的魅力体验算法的魅力——数据结构(另一棵树的子树)数据结构(另一棵树的子树)
给定两个非空二叉树给定两个非空二叉树 s 和和 t,检验,检验 s 中是否包含和中是否包含和 t 具有相同结构和节点值的子树。具有相同结构和节点值的子树。s 的一个子树包括的一个子树包括 s 的一个节点和这个节点的所有子孙。的一个节点和这个节点的所有子孙。s 也可以看做也可以看做
它自身的一棵子树。它自身的一棵子树。
示例 1:
给定的树 s:
3
/ \
4 5
/ \
1 2
给定的树 t:
4
/ \
1 2
返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。
示例 2:
给定的树 s:
3
/ \
4 5
/ \
1 2
/
0
给定的树 t:
4
/ \
1 2
返回 false。
方法一:方法一:DFS 暴力匹配暴力匹配
思路和算法思路和算法
这是一种最朴素的方法 —— DFS 枚举 s 中的每一个节点,判断这个点的子树是否和 t 相等。如何判断一个节点的子树是否和 t相等呢,我们又需要做一次
DFS 来检查,即让两个指针一开始先指向该节点和 t 的根,然后「同步移动」两根指针来「同步遍历」这两棵树,判断对应位置是否相等。
c++
class Solution {
public:
bool check(TreeNode *o, TreeNode *t) {
if (!o && !t) return true;
if ((o && !t) || (!o && t) || (o->val != t->val)) return false;
return check(o->left, t->left) && check(o->right, t->right);
}
bool dfs(TreeNode *o, TreeNode *t) {
if (!o) return false;
return check(o, t) || dfs(o->left, t) || dfs(o->right, t);
}
bool isSubtree(TreeNode *s, TreeNode *t) {
return dfs(s, t);
}
};
java
public boolean isSubtree(TreeNode s, TreeNode t) {
if(t==null) {//t=null,一定都是true
return true;
}
if(s==null) {//t一定不为null.只要s=null,就是false
return false;
}
return isSubtree(s.left,t)||isSubtree(s.left, t)||isSameTree(s,t);
}
//判断两客树是否相同
private boolean isSameTree(TreeNode s, TreeNode t) {
// TODO Auto-generated method stub
if(s==null&&t==null) {
return true;
}
if(s==null||t==null) {
return false;
}
if(s.val!=t.val) {
return false;
}
return isSameTree(s.left,t.left)&&isSameTree(s.right, t.right);
}