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?
Edit:
I understand now. Since strings are bring used, the concatenation takes O(n) time in each recursive call taking overall complexity to O(n2).
The number of the nodes in the tree will be in the range [1, 10^4]
), 所以是 dfs * String hash = O(n^2)
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
}
}