二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

image

节点 0 和节点 5 的最近公共祖先是 2。

  1. 从根节点开始遍历,到目标节点p,得到 [root, x,y,z,... p],将之用 list 保存
  2. 从根节点开始遍历,到目标节点q, 得到 [root,x,y,z,....q],将之用 list 保存
  3. 寻找这2个 list 的最后一个 相同 的节点,该节点就是:最近公共祖先节点
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        List<TreeNode> pNodePathList = getPath(root, p);
        List<TreeNode> qNodePathList = getPath(root, q);

        //寻找 pNodePathList 和 qNodePathList 中第一个不相同的 node, 该 node 就是最近的公共父节点
        TreeNode ancestorNode = null;
        for (int i = 0, j = 0; i < pNodePathList.size() && j < qNodePathList.size(); i++, j++) {
            if (pNodePathList.get(i) == qNodePathList.get(j)) {
                ancestorNode = pNodePathList.get(i);
            }else {
                //分叉节点,说明已经 不公共 了,不需要再继续遍历下去了
                break;
            }
        }
        return ancestorNode;        
    }


    /**
     * 记录从根节点 root 到 node 节点,所经历的所有节点(路径)
     * @param root
     * @param target
     * @return [root, x,y,z..., target]
     */
    private List<TreeNode> getPath(TreeNode root, TreeNode target) {
        List<TreeNode> pathList = new LinkedList<>();

        TreeNode current = root;
        while (current != target) {
            pathList.add(current);
            if (current.val < target.val) {
                //说明 node 在当前节点的 右子树
                current = current.right;
            } else {
                //node 在当前节点的 左子树
                current = current.left;
            }
        }

        //
        pathList.add(target);
        return pathList;
    }
}

参考:https://leetcode.cn/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/description/

posted @ 2023-07-21 23:38  大熊猫同学  阅读(17)  评论(0编辑  收藏  举报