将每一棵子树都序列化称一个字符串,并保证相同的子树会被序列化成相同的子串、不同的子树会被序列化成不同的子串。只要使用一个哈希表存储所有子树的序列化结果,如果某个结果出现超过一次,就能发现一类重复子树。
序列化二叉树的方法可以使用层次遍历,也可以使用递归进行序列化。这里使用深度优先搜索的方法递归序列化二叉树并存入哈希表,遍历时遇到重复的子树序列化结果就可以加入结果数组中。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
def dfs(node):
if not node:
return ""
serial = "".join([str(node.val), "(", dfs(node.left), ")(", dfs(node.right), ")"])
if (tree := seen.get(serial, None)):
repeat.add(tree)
else:
seen[serial] = node
return serial
seen = dict()
repeat = set()
dfs(root)
return list(repeat)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
Map<String, TreeNode> seen = new HashMap<>();
Set<TreeNode> repeat = new HashSet<>();
public String dfs(TreeNode node) {
if (node == null) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append(node.val);
sb.append("(");
sb.append(dfs(node.left));
sb.append(")(");
sb.append(dfs(node.right));
sb.append(")");
String serial = sb.toString();
if (seen.containsKey(serial)) {
repeat.add(seen.get(serial));
} else {
seen.put(serial, node);
}
return serial;
}
public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
dfs(root);
return new ArrayList<TreeNode>(repeat);
}
}
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
unordered_map<string, TreeNode*> seen;
unordered_set<TreeNode*> repeat;
public:
string dfs(TreeNode* node) {
if (!node) {
return "";
}
string serial = to_string(node->val) + "(" + dfs(node->left) + ")(" + dfs(node->right) + ")";
if (auto tree = seen.find(serial); tree != seen.end()) {
repeat.insert(tree->second);
} else {
seen[serial] = node;
}
return serial;
}
vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
dfs(root);
return {repeat.begin(), repeat.end()};
}
};