[LeetCdoe 235] Lowest Common Ancestor of a Binary Tree (Medium)

Given the root and two nodes in a Binary Tree. Find the lowest common ancestor(LCA) of the two nodes.
The lowest common ancestor is the node with largest depth which is the ancestor of both nodes.
Return null if LCA does not exist.

Example

For the following binary tree:

  4
 / \
3   7
   / \
  5   6
LCA(3, 5) = 4
LCA(5, 6) = 7
LCA(6, 7) = 7

思路

比如例题中找3,5的LCA


Picture1.png
  1. 遍历树,找遍历的节点是否为target。
  2. 如果当前root 为空,则返回null。
  3. 如果当前root为target,则返回该root。
  4. 如果当前root,其left child为空,只有right child不为空那么返回right child。反之亦然
  5. 如果当前root,left child 和 right child都不为空,则说明找到了LCA,返回当前root
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return root;
        }
        
        TreeNode result = helper(root, p, q);
        return result;
    }
    
    private TreeNode helper(TreeNode root, TreeNode p, TreeNode q) {
        // stop条件: 如果root为空,则返回null
        if (root == null) {
            return null;
        }
        
        TreeNode leftNode = helper(root.left, p, q);
        TreeNode rightNode = helper(root.right, p, q);
        
        // 1. 找到当前root是一个target,就返回这个root
        if (root == p || root == q) {
            return root;
        }
        
        //2. 当前root下的分支其中包含了某个target,就把这个target 返回出去。
        if (leftNode != null && rightNode == null) {
            return leftNode;
        }
        
        if (rightNode != null && leftNode == null) {
            return rightNode;
        }
        
        //3. 如果root的左、右child分支都已经找到了target,那么说明当前的root就是最小公共节点了,直接返回当前root
        if (leftNode != null && rightNode != null) {
            return root;
        }
        return null;
    }
}

Solution2: 第二部分是BST的代码,根据BST全部右大于root,全部左小于root的特性。根据p 和q的值来缩小检索范围

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    // bottom - up
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return root;
        }
        /*************** BINARY TREE Solution:无法根据左右值大小缩小检索范围 *******************/
        // If either p or q matches with root's key, report 
        // the presence by returning root (Note that if a key is 
        // ancestor of other, then the ancestor key becomes LCA
        if (root.val == p.val || root.val == q.val) {
            return root;
        }
        
        TreeNode left = lowestCommonAncestor (root.left, p, q);
        TreeNode right = lowestCommonAncestor (root.right, p, q);
        
        // If both of the above calls return Non-NULL, then one key 
        // is present in once subtree and other is present in other, 
        // So this node is the LCA 
        if (left != null && right != null) {
            return root;
        }
        
        // Otherwise check if left subtree or right subtree is LCA 
        // 例如p q分别是2,4. 找到6的左子树2找到了,直接返回node2。并没有再向下找了。
        // 但是右子树 8 这边就没有找到返回null。
        // 但因为题目给出的条件就是 一定能在BST中找到P and Q。所以此种情况表明2就肯定是LCA
        return left != null ? left : right;
        /*************** BINARY TREE Solution:END*******************/
        ///////
        ///////
        ///////
        
        /*************** BST Solution *******************/
        // 1. 如果p, q都在node的左边(不包含),那么就搜左子树
        // 2. 如果p, q都在node的右边(不包含),那么就搜右子树
        // 3。如果p,q在node两侧,或者node 等于 p或者q,那么就找到了直接返回当前node
        
        if (root.val > p.val && root.val > q.val) {
            return lowestCommonAncestor (root.left, p, q);
        }
        
        if (root.val < p.val && root.val < q.val) {
            return lowestCommonAncestor (root.right, p, q);
        }
        
        return root;
        /*************** BST Solution END*******************/
    }
    
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容