236. Lowest Common Ancestor of a Binary Tree

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
“The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______3______
       /              \
    ___5__          ___1__
   /      \        /      \
   6      _2       0       8
         /  \
         7   4

For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

Solution1:post-order / 分治 遞歸

思路:因為題目中是說給given two nodes音比,說明并一定在tree里面 且 是reference所以不會有重復(fù)多次匹配情況织堂。
所以可以比較巧妙地 分治divide只分別關(guān)注sub_left_tree和sub_right_tree中先碰到的任意兩者之一的位置箭阶,conquer時情況1如果左右都找到(必定一個是p一個是q的位置)則向上返回當(dāng)前root作為目前LCA,情況2如果左或右只找到一個位置(說明兩個都在這個位置的子樹下 或是 只有一個在) 就向上返回這個位置(以后這個位置會被更新if 另一個在別的地方找到(那個root點的情況1))聘裁。
Time Complexity: O(N) Space Complexity: O(N) 遞歸緩存

Solution2:Iterative

思路:iterative 遍歷的同時需要將parent關(guān)系保存下來
(1) 建立parent map
(2) 在parent中尋找p q 的 LCA

屏幕快照 2017-09-08 下午1.15.50.png

Time Complexity: O(N) Space Complexity: O(N)

Solution3:post-order / 分治 遞歸 自Round1

Time Complexity: O(N) Space Complexity: O(N) 遞歸緩存

Solution1 Code:

class Solution1 {
    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)
            return right;
        else if (right == null)
            return left;
        else
            return root;
    }
}

Solution2 Code:

public class Solution2 {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        Map<TreeNode, TreeNode> parent = new HashMap<>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        
        parent.put(root, null);
        stack.push(root);
        while (!parent.containsKey(p) || !parent.containsKey(q)) {
            TreeNode node = stack.pop();
            if (node.left != null) {
                parent.put(node.left, node);
                stack.push(node.left);
            }
            if (node.right != null) {
                parent.put(node.right, node);
                stack.push(node.right);
            }
        }
        
        Set<TreeNode> ancestors = new HashSet<>();
        while (p != null) {
            ancestors.add(p);
            p = parent.get(p);
        }
        
        while (!ancestors.contains(q))
            q = parent.get(q);
        return q;
    }
}

Solution3_Round1 Code:

class Solution {
    
    class Pack {
        public boolean p;
        public boolean q;

        Pack() {
            p = false;
            q = false;
        }
    }

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        return dfs(root, p, q, new Pack());
    }
    
    private TreeNode dfs(TreeNode root, TreeNode p, TreeNode q, Pack pack) {
        // terminal
        if(root == null) return null;
        
        // divide
        Pack pack_left = new Pack();
        TreeNode result_left = dfs(root.left, p, q, pack_left);
        if(result_left != null) return result_left;
        
        Pack pack_right = new Pack();
        TreeNode result_right = dfs(root.right, p, q, pack_right);
        if(result_right != null) return result_right;
        
        // conquer
        pack.p = pack_left.p || pack_right.p;
        pack.q = pack_left.q || pack_right.q;
        
        if(root == p) {
            pack.p = true;
        }
        else if(root == q) {
            pack.q = true;
        }
        
        if(pack.p && pack.q) {
            return root;
        }
        return null;
        
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子握恳,更是在濱河造成了極大的恐慌挖帘,老刑警劉巖完丽,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拇舀,居然都是意外死亡逻族,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門骄崩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來聘鳞,“玉大人薄辅,你說我怎么就攤上這事】倭В” “怎么了站楚?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長搏嗡。 經(jīng)常有香客問我窿春,道長,這世上最難降的妖魔是什么采盒? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任旧乞,我火速辦了婚禮,結(jié)果婚禮上磅氨,老公的妹妹穿的比我還像新娘尺栖。我一直安慰自己,他們只是感情好悍赢,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布决瞳。 她就那樣靜靜地躺著,像睡著了一般左权。 火紅的嫁衣襯著肌膚如雪皮胡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天赏迟,我揣著相機與錄音屡贺,去河邊找鬼。 笑死锌杀,一個胖子當(dāng)著我的面吹牛甩栈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播糕再,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼量没,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了突想?” 一聲冷哼從身側(cè)響起殴蹄,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎猾担,沒想到半個月后袭灯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡绑嘹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年稽荧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片工腋。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡姨丈,死狀恐怖畅卓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情构挤,我是刑警寧澤髓介,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站筋现,受9級特大地震影響唐础,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜矾飞,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一一膨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧洒沦,春花似錦豹绪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至括尸,卻和暖如春巷蚪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背濒翻。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工屁柏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人有送。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓淌喻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雀摘。 傳聞我的和親對象是個殘疾皇子裸删,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容