236. Lowest Common Ancestor of a Binary Tree (M)

本文探讨了在普通二叉树中寻找两个指定节点的最近公共祖先(LCA)的两种方法:递归搜索和迭代Hash。通过实例展示了如何在给定的二叉树中找到节点5和1、节点5和4的最近公共祖先。

Lowest Common Ancestor of a Binary Tree (M)

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]

在这里插入图片描述

Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

Example 2:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

Note:

  • All of the nodes’ values will be unique.
  • p and q are different and both values will exist in the binary tree.

题意

在一个普通二叉树中找到两个指定结点的最近公共祖先。

思路

**递归:**递归搜索整棵树,对于当前结点x,如果能在它的左边和右边找到p和q,或者x就是p、q中的一个,并且在它的左边或右边能找到另一个指定结点,那么x就是要求的最近公共祖先。

**迭代Hash:**遍历整棵树,记录所有结点的父结点信息。从p出发,将p和其所有父结点存入set;再从q出发,沿父结点向上遍历,则第一个在set中出现的结点就是所求的最近公共祖先。


代码实现 - 递归

class Solution {
    private TreeNode lca;

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        findTree(root, p, q);
        return lca;
    }

    // 只要能找到p或q就返回true
    private boolean findTree(TreeNode x, TreeNode p, TreeNode q) {
        if (x == null) {
            return false;
        }

        boolean self = x == p || x == q;
        boolean left = findTree(x.left, p, q);
        boolean right = findTree(x.right, p, q);

        // 满足三种情况任意一种就能确定找到了lca
        if (left && right || self && right || self && left) {
            lca = x;
        }

        return self || left || right;
    }
}

代码实现 - 迭代Hash

class Solution {
    Map<TreeNode, TreeNode> parent = new HashMap<>();

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        dfs(root, null);

        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;
    }

    // 生成HashMap
    private void dfs(TreeNode cur, TreeNode pre) {
        if (cur == null) {
            return;
        }

        parent.put(cur, pre);
        dfs(cur.left, cur);
        dfs(cur.right, cur);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值