编程语言
首页 > 编程语言> > 【算法】求二叉树两个节点的最低公共祖先节点

【算法】求二叉树两个节点的最低公共祖先节点

作者:互联网

左程云算法与数据结构课 https://www.bilibili.com/video/BV13g41157hK?p=2&spm_id_from=pageDriver

题目

给定两个二叉树的节点node1和node2,找到他们的最低公共祖先节点。

题解

解法一

设置一个 HashMap 保存节点与该节点的父节点(设根节点的父节点为本身),然后再用一个集合 set1 保存 node1 的全部祖先节点,对node2往上求祖先节点,看是否在 set1 中,若在,则这个节点即为最低公共祖先节点。

//前提:node1和node2一定属于head为头的树
//返回node1和node2的最低公共祖先
public static Node lca(Node head, Node node1, Node node2) {
    HashMap<Node, Node> fatherMap = new HashMap<>(); //保存节点与该节点的父节点
    fatherMap.put(head, head); //根节点的父节点为本身
    process(head, fatherMap);  //求所有节点的父节点
    HashSet<Node> set1 = new HashSet<>(); //node1 的祖先节点集合
    Node cur = node1;
    //求 node1 的祖先节点,并放入set1中 
    while (cur != fatherMap.get(cur)) { //回溯到根节点时停止
        set1.add(cur);
        cur = fatherMap.get(cur);
    }
    set1.add(head);

    //求 node2 的祖先节点
    cur = node2;
    while (!set1.contains(cur)) { //set1 中含该节点时停止
        cur = fatherMap.get(cur);
    }
    //该节点即为最低公共祖先节点
    return cur;
}
//递归求除根节点外所有节点的父节点,保存在 fatherMap 中
private static void process(Node head, HashMap<Node, Node> fatherMap) {
    if (head == null) {
        return;
    }
    fatherMap.put(head.left, head);
    fatherMap.put(head.right, head);
    process(head.left, fatherMap);
    process(head.right, fatherMap);
}

解法二

在二叉树中有两种情况:

image-20220122232822714

image-20220122232855230

试想这么一个递归操作:

在这个递归操作中,有以下情况:

通过上面的刨析,就能写出下面优美的代码了。

public static Node lowestCommonAncestor(Node head, Node node1, Node node2) {
    if (head == null || head == node1 || head == node2) { //base case
        return head;
    }
    Node left = lowestCommonAncestor(head.left, node1, node2);
    Node right = lowestCommonAncestor(head.right, node1, node2);
    if (left != null && right != null) {
        return head;
    }
    return left != null ? left : right;
}

标签:head,祖先,fatherMap,算法,二叉树,node1,node2,节点
来源: https://www.cnblogs.com/hzyuan/p/15835556.html