二叉樹中兩個節點的最近公共祖先


一、遞歸版本

思想:假設根結點為root,其中給定的兩個結點分別為A和B,它們分別都不為null。如果當前結點p為null,那么直接返回null,如果當前結點p是給定的結點中的其中一個結點,那么直接返回當前結點p(如果p是根結點,程序一次就返回了,下面的遞歸也不會出現)。如果當前節點不是A和B中的一個,那么需要分別去查找p的左右子樹,看看是否包含A或者B,查詢左右子樹后,如果查詢左子樹和查詢右子樹的結果都不為null,說明當前結點p就是最近的公共祖先。否則,如果查詢左子樹結果為null,那么返回查詢右子樹的結果。反之,返回查詢左子樹的結果。

public static TreeNode getParent(TreeNode root, TreeNode node1,TreeNode node2) {
        if(root == null || node1 == null ||  node2 == null) return null;
        //這里可以換成if(root == node1 || root == node2),我只是為了方便測試才這樣寫
        if(root.val == node1.val || root.val == node2.val) return root;
        TreeNode left = getParent(root.left,node1,node2);
        TreeNode right = getParent(root.right,node1,node2);
        //如果左右子樹都能找到,那么當前節點就是最近的公共祖先節點
        if(left != null && right != null) return root;
        //如果左子樹上沒有,那么返回右子樹的查找結果
        if(left == null) return right;
        //否則返回左子樹的查找結果
        else return left;
    }

二、非遞歸版本

思想:這里提供一種思路,代碼就不演示了。因為這個思想的實現代碼和查找從根到某個結點的路徑的思想一樣。首先,我們找出一條從根到A的路徑保存到棧或者數組,相同的方式找到一條從根到B的路徑也保存到棧或者數組(參考我的另一篇博客:查找從根到某結點的路徑)。然后開始遍歷這兩個數組,找到第一次下標相同但是值不同的那么數的下標,這個下標的前一個數就是最近公共祖先。我舉個例子:

假設A為結點3,B為結點4,那么從根到A的路徑為9---8---6---3,從根到B的路徑為9---7---4,遍歷這個兩個數組,發現9 == 9,而8 != 7,所以9就是最近公共祖先。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM