The question is to find whether a given sum exists over any path in a BST. The question is damn easy if a path means root to leaf, or easy if the path means a portion of a path from root to leaf that may not include the root or the leaf. But it becomes difficult here, because a path may span both left and right child of a node. For example, in the given figure, a sum of 132 exists over the circled path. How can I find the existence of such a path? Using hash to store all possible sums under a node is frowned upon!

You can certainly generate all possible paths, summing incrementally as you go. The fact that the tree is a BST might let you save time by bounding out certain sums, though I’m not sure that will give an asymptotic speed increase. The problem is that a sum formed using the left child of a given node will not necessarily be less than a sum formed using the right child, since the path for the former sum could contain many more nodes. The following algorithm will work for all trees, not just BSTs.
To generate all possible paths, notice that the topmost point of a path is special: it’s the only point in a path which is allowed (though not required) to have both children contained in the path. Every path contains a unique topmost point. Therefore the outer layer of recursion should be to visit every tree node, and to generate all paths that have that node as the topmost point.
The above pseudocode only reports the topmost node in the path. The entire path can be reconstructed by having
EnumerateSums()return a list of pairs(sum, goesLeft)instead of a plain list of sums, wheregoesLeftis a boolean that indicates whether the path used to generate that sum initially goes left from the parent node.The above pseudocode calculates sum lists multiple times for each node:
EnumerateSums(t)will be called once for each node abovetin the tree, in addition to being called fortitself. It would be possible to makeEnumerateSums()memoise the list of sums for each node so that it’s not recomputed on subsequent calls,but actually this doesn’t improve the asymptotics: only O(n) work is required to produce a list of n sums using the plain recursion, and changing this to O(1) doesn’t change the overall time complexity because the entire list of sums produced by any call toEDIT: As pointed out by Evgeny Kluev,EnumerateSums()must in general be read by the caller anyway, and this requires O(n) time.EnumerateSums()actually behaves like a merge sort, being O(nlog n) when the tree is perfectly balanced and O(n^2) when it is a single path. So memoisation will in fact give an asymptotic performance improvement.It is possible to get rid of the temporary lists of sums by rearranging
EnumerateSums()into an iterator-like object that performs the list merge lazily, and can be queried to retrieve the next sum in increasing order. This would entail also creating anEnumerateSumsDown()that does the same thing but retrieves sums in decreasing order, and using this in place ofreverse(append(0, EnumerateSums(t.right))). Doing this brings the space complexity of the algorithm down to O(n), where n is the number of nodes in the tree, since each iterator object requires constant space (pointers to left and right child iterator objects, plus a place to record the last sum) and there can be at most one per tree node.