Lowest Common Ancestor Algorithm

前端 未结 6 1729
感动是毒
感动是毒 2021-02-05 17:42

So I have been looking into implementing a lowest common ancestor algorithm. I looked at many different algorithms (mainly variations of Trajan\'s solution or variations of the

6条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-05 18:23

    As others have mentioned, your algorithm is currently quadratic. That may not be a problem for a dataset as small as 50-75 nodes, but in any case it's straightforward to change it to linear time without using any sets or hashtables, just by recording the complete path to the root for each node, then walking back down from the root and looking for the first different node. The immediately preceding node (which is the common parent of these 2 different nodes) is then the LCA:

    linearLCA(node1, node2) {
        parentNode1 := [ ]
        while (node1!=NULL) {
             parentNode1.push(node1)
             node1 := node1.parent
        }
        parentNode2 := [ ]
        while (node2!=NULL) {
             parentNode2.push(node2)
             node2 := node2.parent
        }
        while (node1 == node2 && !isEmpty(parentNode1) && !isEmpty(parentNode2)) {
            oldNode := node1
            node1 := parentNode1.pop()
            node2 := parentNode2.pop()
        }
        if (node1 == node2) return node1    // One node is descended from the other
        else return oldNode                 // Neither is descended from the other
    }
    

    EDIT 27/5/2012: Handle the case in which one node is descended from the other, which would otherwise result in attempting to pop() an empty stack. Thanks to damned for pointing this out. (I also realised that it's sufficient to track a single oldNode.)

提交回复
热议问题