樹中兩個(gè)節(jié)點(diǎn)的最低共同祖先系列

這道題有好幾種情況,每種情況有不同的解法

一. 這棵樹是滿二叉樹,且節(jié)點(diǎn)從左到右、從上到下按順序標(biāo)記為1,2,3,...

滿二叉樹的子節(jié)點(diǎn)與父節(jié)點(diǎn)之間的關(guān)系為root = child / 2
兩個(gè)節(jié)點(diǎn)a,b,哪個(gè)節(jié)點(diǎn)大就將其標(biāo)記 / 2,直到兩個(gè)節(jié)點(diǎn)標(biāo)記相同,就得到了最低公共祖先
牛客網(wǎng)鏈接

public class LCA {
    public int getLCA(int a, int b) {
        if(a < 1 || b < 1) return -1;
        while(a != b){
            if(a < b){
                b /= 2;
            }else{
                a /= 2;
            }
        }
        return a;
    }
}

二. 這是一顆二叉搜索樹

leetcode鏈接
根據(jù)二叉搜索樹的性質(zhì),共同祖先節(jié)點(diǎn)要么是兩個(gè)節(jié)點(diǎn)之一,要么是值在二者之間,根據(jù)這一性質(zhì)從根節(jié)點(diǎn)開始掃描

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) return null;
        if(p == null) return q;
        if(q == null) return p;
        while(root != p && root != q){
            if(root.val > p.val && root.val > q.val){
                root = root.left;
            }else if(root.val < p.val && root.val < q.val){
                root = root.right;
            }else{
                return root;
            }
        }
        return root;
    }
}

三. 這是一顆普通的二叉樹

leetcode鏈接
這種情況下有兩種方案:

  1. 采用遞歸先序遍歷的方法,分別從左右子樹中找目標(biāo)節(jié)點(diǎn),如果左子樹中找到了二者,則返回左子樹,如果右子樹找到了二者則返回右子樹;左右子樹各找到一個(gè),則返回當(dāng)前節(jié)點(diǎn)。
  2. 先序遍歷記錄兩個(gè)節(jié)點(diǎn)的路徑,再比較路徑找到最低共同祖先,這種方法是劍指offer上的方法,但是實(shí)現(xiàn)起來比較復(fù)雜,實(shí)現(xiàn)后測(cè)試效果反而不如1的好。

經(jīng)實(shí)現(xiàn)比較,方法1的效率更高,這里給出方法1的代碼

public class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == p || root == q)  return root;
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if(left != null && right != null)   return root;
        return left != null ? left : right;
    }
}

四. 除root節(jié)點(diǎn)外,其余節(jié)點(diǎn)都有指向父節(jié)點(diǎn)的指針

這個(gè)就容易很多了,直接將兩個(gè)目標(biāo)節(jié)點(diǎn)通過指向父節(jié)點(diǎn)的指針一直找到root,記錄下路徑,再反向找到這兩個(gè)路徑要分叉的結(jié)點(diǎn)就是最低公共祖先。

五. 這是一顆普通的樹,非二叉

跟三的做法是一樣的,DLRRRRR

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容