As Tarjan's off-line least common ancestors is offline, you may wish to approach the problem by another route. Using a bredth-first or depth-first search, find the path's of each item in your search list. Then, you can use these paths to determine the lowest common ancestor.
The psuedo-code would be something like:
- iterate over all nodes in tree
- if node is in search list, record path (from node ids)
- after all nodes have been searched, start at the first path id of each search list node
- if first id is identical for all nodes move to next id
- repeat step 4 until at least one id is different. The previous id is the least common ancestor.
For example, with your search list example of , you would build the following path index
H -> ABDH
I -> ABEI
J -> ABEJ
E -> ABE
Now, you can see all nodes have a A at position 1. As well as a B at position 2. However, at position 3, H has a D which doesn't match the other nodes. Thus node B is the least common ancestor.
Obviously there are corner cases. If the search list has only one item, it is the least common ancestor. Likewise, if you are comparing the paths and you reach the node itself, it is the common ancestor.