My answer is O(n^2), but I believe it is accurate, and takes a slightly different approach and looks easier to implement.
Assume the value stored at node i is denoted by VALUE[i]. My idea is to store at each node the sum of the values on the path from root to that node. So for each node i, SUM[i] is sum of path from root to node i.
Then for each node pair (i,j), find their common ancestor k. If SUM(i)+SUM(j)-SUM(k) = TARGET_SUM, you have found an answer.
This is O(n^2) since we are looping over all node pairs. Although, I wish I can figure out a better way than just picking all pairs.
We could optimize it a little by discarding subtrees where the value of the node rooted at the subtree is greater than TARGET_SUM. Any further optimizations are welcome :)
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)
Function common_ancestor is a pretty standard problem for a binary search tree. Psuedocode (from memory, hopefully there are no errors!):
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