class Solution(object):
def findDuplicateSubtrees(self, root):
"""
:type root: TreeNode
:rtype: List[TreeNode]
"""
def dfs(root):
if not root: return ''
ans = ''
if not root.left and not root.right:
ans = str(root.val)
else:
ans = str(root.val) + "(" + dfs(root.left) + "," + dfs(root.right) + ")"
table[ans].append(root)
return ans
table = collections.defaultdict(list)
dfs(root)
return [table[elem][0] for elem in table if len(table[elem]) > 1]
class Solution {
public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
List<TreeNode> res = new ArrayList<>();
Map<String, List<TreeNode>> map = new HashMap<>();
helper(root, map, res);
for (Map.Entry<String, List<TreeNode>> entry : map.entrySet()) {
List<TreeNode> nodeList = entry.getValue();
if (nodeList.size() > 1) res.add(nodeList.get(0));
}
return res;
}
private String helper(TreeNode root, Map<String, List<TreeNode>> map, List<TreeNode> res) {
if (root == null) return "#";
String left = helper(root.left, map, res);
String right = helper(root.right, map, res);
String ret = root.val + "," + left + "," + right;
if (! map.containsKey(ret)) map.put(ret, new ArrayList<>());
map.get(ret).add(root);
return ret;
}
}
class Solution {
public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
List<TreeNode> res = new ArrayList<>();
helper(root, new HashSet<>(), new HashSet<>(), res);
return res;
}
// return inorder serialization of root, add the string into hashSet
private String helper(TreeNode root, Set<String> set, Set<String> resSet, List<TreeNode> res) {
if (root == null) return "#";
String left = helper(root.left, set, resSet, res);
String right = helper(root.right, set, resSet, res);
String ret = root.val + "," + left + "," + right;
if (! set.add(ret) && resSet.add(ret)) res.add(root); // set.add() 返回 false 说明set中已经存在
return ret;
}
}
class Solution {
// post-order traverse, serialize, store string in hashSet, if found a string already in set,
// means we have found a dup tree
string helper(TreeNode* root, unordered_set<string>& count_set, vector<TreeNode*>& res, unordered_set<string>& res_set) {
if (root == nullptr) return "#";
string left_str = helper(root->left, count_set, res, res_set);
string right_str = helper(root->right, count_set, res, res_set);
string curr_str = left_str + "," + right_str + "," + to_string(root->val);
if (count_set.insert(curr_str).second == false) {
if (res_set.insert(curr_str).second == true) res.push_back(root);
}
return curr_str;
}
public:
vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
unordered_set<string> count_set;
unordered_set<string> res_set;
vector<TreeNode*> res;
if (root == nullptr) return res;
helper(root, count_set, res, res_set);
return res;
}
};