给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
示例 1:
输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true
示例 2:
输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false
题解
解法一 哈希函数
字符串哈希,因为树有两个子树(二叉树)
那么我们可以设字符串哈希函数为 x + left*P + right*Q
x是本节点的结点值,left是左节点的哈希值,right是右节点哈希值,P,Q为自己设置的离散值
class Solution {
public:
const int P = 131, Q = 159, MOD = 1e4+10;
int T= -1;
bool flag = false;
int dfs(TreeNode * root){
if(!root) return 12345;
int left = dfs(root->left), right = dfs(root->right);
int x = (root->val %MOD + MOD) % MOD;
if(left == T || right == T) flag = true;
return (x + left*P + right*Q) % MOD;
}
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
T = dfs(subRoot);
if(dfs(root) == T){
flag = true;
}
return flag;
}
};
解法二 递归
dfs函数不断递归每一层的root的子树,比对是否有子树和subRoot相等,只要有一个子树和subRoot相同,就会返回true
isSame函数可以判断,输入的两个树结构是否完全相同
class Solution {
public:
bool dfs(TreeNode * s,TreeNode *t){ //
if(!s) return false;
return isSame(s, t) || dfs(s->left, t) || dfs(s->right, t);
}
bool isSame(TreeNode *s,TreeNode *t){
if(!s && !t){
return true;
}
if(!s && t || s && !t || s->val!=t->val)
return false;
return isSame(s->left, t->left) && isSame(s->right, t->right);
}
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
return dfs(root,subRoot);
}
};