力扣labuladong——一刷day41

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


如果说笔试的时候经常遇到各种动归回溯这类稍有难度的题目,那么面试会倾向于一些比较经典的问题,难度不算大,而且也比较实用。 本文就用 Git 引出一个经典的算法问题:最近公共祖先(Lowest Common Ancestor,简称 LCA)。 git pull 这个命令我们经常会用,它默认是使用 merge 方式将远端别人的修改拉到本地;如果带上参数 git pull -r,就会使用 rebase 的方式将远端修改拉到本地。 这二者最直观的区别就是:merge 方式合并的分支会看到很多「分叉」,而 rebase 方式合并的分支就是一条直线。但无论哪种方式,如果存在冲突,Git 都会检测出来并让你手动解决冲突。 那么问题来了,Git 是如何检测两条分支是否存在冲突的呢?

一、力扣236. 二叉树的最近公共祖先

/**
 * 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) {
        return fun(root,p.val,q.val);
    }
    public TreeNode fun(TreeNode root ,int val1, int val2){
        if(root == null){
            return null;
        }
        if(root.val == val1 || root.val == val2){
            return root;
        }
        TreeNode lchild = fun(root.left, val1, val2);
        TreeNode rchild = fun(root.right, val1, val2);
        if(lchild != null && rchild != null){
            return root;
        }
        return lchild != null ? lchild : rchild;
    }
}

二、力扣1676. 二叉树的最近公共祖先 IV

/**
 * 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[] nodes) {
        if(root == null){
            return null;
        }
        for(TreeNode n : nodes){
            if(root == n){
                return root;
            }
        }
        TreeNode lchild = lowestCommonAncestor(root.left,nodes);
        TreeNode rchild = lowestCommonAncestor(root.right,nodes);
        if(lchild != null && rchild != null){
            return root;
        }
        return lchild != null ? lchild : rchild;
    }
}

三、力扣1644. 二叉树的最近公共祖先 II

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    boolean flagL = false, flagR = false;
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        TreeNode res = fun(root,p,q);
        if(flagL && flagR){
            return res;
        }
        return null;
    }
    public TreeNode fun(TreeNode root, TreeNode p, TreeNode q){
        if(root == null){
            return null;
        }
        TreeNode lchild = fun(root.left,p,q);
        TreeNode rchild = fun(root.right, p, q);
        if(lchild != null && rchild != null){
            return root;
        }
        if(root == p || root == q){
            if(root == p){
                flagL = true;
                return root;
            }
            if(root == q){
                flagR = true;
                return root;
            }
        }
        return lchild != null ? lchild : rchild; 
    }
}

四、力扣235. 二叉搜索树的最近公共祖先

/**
 * 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.val > p.val && root.val > q.val){
            return lowestCommonAncestor(root.left,p,q);
        }else if(root.val < p.val &&root.val < q.val){
            return lowestCommonAncestor(root.right,p,q);
        }else{
            return root;
        }
    }
}

五、力扣1650. 二叉树的最近公共祖先 III

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node parent;
};
*/

class Solution {
    public Node lowestCommonAncestor(Node p, Node q) {
        while(fun(p,q) == null){
            p = p.parent;
        }
        return p;
    }
    public Node fun(Node p, Node q){
        if(p == null){
            return null;
        }
        if(p == q){
            return p;
        }
        Node l = fun(p.left,q);
        Node r = fun(p.right,q);
        if(l != null){
            return l;
        }
        if(r != null){
            return r;
        }
        return null;
    }
}

链表寻找共同节点操作

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node parent;
};
*/

class Solution {
    public Node lowestCommonAncestor(Node p, Node q) {
        Node a = p, b = q;
        while(a != b){
            if(a == null) a = q;
            else a = a.parent;
            if(b == null) b = p;
            else b = b.parent;
        }
        return a;
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乱世在摸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值