给定二叉树 T S1 S2问是否可以删除T中的一条边得到两个二叉树 结构与S1S2相同 用c++
时间: 2023-11-27 10:49:49 浏览: 83
可以使用深度优先搜索(DFS)来解决此问题。对于每个节点,我们可以计算其左子树和右子树的哈希值,并将其存储在哈希表中。然后,我们递归遍历每个节点,尝试删除该节点的左子树或右子树,并重新计算哈希值。如果新的哈希值与S1或S2的哈希值匹配,则说明我们已经找到了一条边,可以删除它得到两个二叉树结构与S1S2相同。
具体实现代码如下:
```c++
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
bool checkSubtree(TreeNode* t, TreeNode* s1, TreeNode* s2) {
unordered_map<int, vector<TreeNode*>> hash;
dfs(t, hash);
int h1 = hashValue(s1), h2 = hashValue(s2);
for (auto& node : hash[h1]) {
if (isSubtree(node->left, s1) && hashValue(node->left) == h1 && isSubtree(node->right, s2) && hashValue(node->right) == h2) {
return true;
}
}
for (auto& node : hash[h2]) {
if (isSubtree(node->left, s2) && hashValue(node->left) == h2 && isSubtree(node->right, s1) && hashValue(node->right) == h1) {
return true;
}
}
return false;
}
private:
void dfs(TreeNode* node, unordered_map<int, vector<TreeNode*>>& hash) {
if (!node) {
return;
}
int h = hashValue(node);
hash[h].push_back(node);
dfs(node->left, hash);
dfs(node->right, hash);
}
int hashValue(TreeNode* node) {
if (!node) {
return 0;
}
int left = hashValue(node->left);
int right = hashValue(node->right);
return node->val + left * 31 + right * 131;
}
bool isSubtree(TreeNode* s, TreeNode* t) {
if (!s && !t) {
return true;
}
if (!s || !t) {
return false;
}
if (s->val != t->val) {
return false;
}
return isSubtree(s->left, t->left) && isSubtree(s->right, t->right);
}
};
```
其中,`checkSubtree`函数接受三个参数:二叉树T,以及需要匹配的两个二叉树S1和S2。首先,我们使用DFS计算每个节点的哈希值,并将其存储在哈希表中。然后,我们计算S1和S2的哈希值,并在哈希表中查找具有相应哈希值的节点。对于每个节点,我们检查其左子树和右子树是否与S1和S2匹配,并检查它们的哈希值是否与S1和S2的哈希值相同。如果找到了一条边,则返回true。如果遍历完所有节点都没有找到,则返回false。
在实现中,我们还定义了`hashValue`和`isSubtree`两个辅助函数。`hashValue`函数计算二叉树的哈希值,其中使用了31和131两个质数作为哈希因子,可以有效地减少哈希冲突。`isSubtree`函数递归判断两个二叉树是否相同。
需要注意的是,本题假设T中只有一条边可以删除,因此我们只需要遍历T的所有节点即可。如果T中有多条边可以删除,则需要对每条边进行尝试,时间复杂度会大大增加。
阅读全文