Сначала вы создаете список всех путей, а затем, как только они у вас есть, вы вычисляете хэши. Размер списка всех этих путей составляет O (n ^ 3) (есть O (n ^ 2) путей, каждый O (n) длиной) Почему? Почему бы просто не вычислить хеши, когда вы пересекаете дерево? Таким образом, вы возьмете целую единицу n из своей временной сложности.
Код для правильного решения (результат заканчивается передачей в списке целых чисел):
public void getPaths(AbstractTree<String> tree, StringBuilder parentPath,
List<Integer> list)
StringBuilder newPath = parentPath.clone();
newPath.append("/");
newPath.append(tree.getNodeName());
list.add(newPath.toString().hashCode());
if (!tree.isLeaf()){
Iterator<AbstractTree<String>> child = tree.getChildren().iterator();
for (AbstractTree<String> child : tree.getChildren()){
getPaths(child, newPath, list)
}
}
}
Это все еще O (n ^ 2). Это происходит из-за хэширования строк O (n ^ 2) (каждый узел имеет длину пути, пропорциональную его глубине), и вы можете уменьшить его даже до O (N), если у вас есть хеш, который для данного узла занимает только хеш пути его родителей и каким-то образом его изменяет.
Дальнейшие оптимизации включают в себя: - параллельный обход дерева - использование более умного хеширования (т. е. хеш дочернего элемента является функцией дочернего элементаи хеш родительского пути, а не всего родительского пути).