Can anyone explain how the first solution is O(n^2)? My understanding is that it pretty much does the same thing as second solution. Arent both O(n) - n being number of nodes in the tree?
The number of the nodes in the tree will be in the range [1, 10^4]
), 所以是 dfs * String hash = O(n^2)
@shiyuluu is right. Concatenating in string isn't a main problem here. The problem is building hash from all seeing nodes fast.
If you want to build a hash from a string, you have to go through all the letters of that string. Each letter of this string is one node. Therefore, the first solution has a complexity of n ^ 2.
class Solution {
public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
Map<String, Integer> countMap = new HashMap<>();
Map<String, Integer> idMap = new HashMap<>();
List<TreeNode> res = new ArrayList<>();
serialization(root, idMap, countMap, res);
return res;
}
// the num of nodes can be 10^4, so serialization string may be too long, it casues hashmap confliction
// the goal is reduce serialization string to a "short id"
private int serialization(TreeNode root, Map<String, Integer> idMap, Map<String, Integer> countMap, List<TreeNode> res) {
if (root == null) {
return -1;
}
String key = root.val + "," +
serialization(root.left, idMap, countMap, res) + "," +
serialization(root.right, idMap, countMap, res);
if (!idMap.containsKey(key)) {
// when there is new key to add, idMap.size() will increase, so it's a unique number
// idMap.size() be the short id, or use a global variable is also ok
idMap.put(key, idMap.size());
countMap.put(key, 1); // countMap part is just like solution1's map
} else {
countMap.put(key, countMap.get(key)+1);
if (countMap.get(key) == 2) {
res.add(root);
}
}
return idMap.get(key); // return uid
}
}