Мой ответ O(n^2)
, но я считаю, что он точен, и использует слегка другой подход и выглядит более простым для реализации.
Предположим, значение хранится в узле i
обозначается VALUE[i]
.Моя идея состоит в том, чтобы хранить в каждом узле сумму значений на пути от root
до этого узла.Таким образом, для каждого узла i
, SUM[i]
является суммой пути от root
до узла i
.
Затем для каждой пары узлов (i,j)
найдите их общего предка k
.Если SUM(i)+SUM(j)-SUM(k) = TARGET_SUM
, вы нашли ответ.
Это O(n^2)
, так как мы выполняем цикл по всем парам узлов.Хотя мне бы хотелось найти лучший способ, чем просто выбрать все пары.
Мы могли бы немного оптимизировать его, отбрасывая поддеревья, где value
узла, корни которого в поддереве, больше TARGET_SUM
,Любая дальнейшая оптимизация приветствуется:)
Psuedocode:
# Skipping code for storing sum of values from root to each node i in SUM[i]
for i in nodes:
for j in nodes:
k = common_ancestor(i,j)
if ( SUM[i] + SUM[j] - SUM[k] == TARGET_SUM ):
print_path(i,k,j)
Функция common_ancestor
является довольно стандартной проблемой для двоичного дерева поиска.Psuedocode (из памяти, надеюсь, ошибок нет!):
sub common_ancestor (i, j):
parent_i = parent(i)
# Go up the parent chain until parent's value is out of the range.
# That's a red flag.
while( VAL[i] <= VAL[parent_i] <= VAL[j] ) :
last_parent = parent_i
parent_i = parent(i)
if ( parent_i == NULL ): # root node
break
return last_parent