📌  相关文章
📜  二叉树中离给定节点最近的叶子(1)

📅  最后修改于: 2023-12-03 15:21:40.049000             🧑  作者: Mango

二叉树中离给定节点最近的叶子

简介

在二叉树中,找到离给定节点最近的叶子节点是一道常见的问题。这个问题通常可以通过深度优先搜索或广度优先搜索来解决。

解决方法

在深度优先搜索中,我们可以递归地遍历树,并跟踪到给定节点的路径。一旦我们到达给定节点,我们可以从这个节点开始,尝试找到离它最近的叶子节点。为此,我们可以使用一个队列,将当前节点和它与根节点的距离入队。然后,我们依次出队,并检查当前节点是否是叶子节点。如果是,则返回当前节点和距离;否则,我们将当前节点的子节点和距离加一入队。然后我们从队列的头部重新开始这个过程,直到找到叶子节点。

public static class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
    }
}

public static TreeNode findClosestLeaf(TreeNode root, TreeNode k) {
    Map<TreeNode, TreeNode> parents = new HashMap<>();
    dfs(root, null, k, parents);

    Queue<TreeNode> q = new LinkedList<>();
    Set<TreeNode> seen = new HashSet<>();
    q.offer(k);
    seen.add(k);

    while (!q.isEmpty()) {
        TreeNode node = q.poll();
        if (isLeaf(node)) {
            return node;
        }
        if (node.left != null && seen.add(node.left)) {
            q.offer(node.left);
        }
        if (node.right != null && seen.add(node.right)) {
            q.offer(node.right);
        }
        if (parents.containsKey(node) && seen.add(parents.get(node))) {
            q.offer(parents.get(node));
        }
    }
    throw new IllegalArgumentException("no leaf found");
}

private static boolean isLeaf(TreeNode node) {
    return node.left == null && node.right == null;
}

private static void dfs(TreeNode node, TreeNode parent, TreeNode k, Map<TreeNode, TreeNode> parents) {
    if (node == null) {
        return;
    }
    if (node == k) {
        if (isLeaf(node)) {
            parents.put(node, null);
        } else if (node.left != null) {
            TreeNode leaf = findLeaf(node.left);
            parents.put(node, leaf);
        } else {
            TreeNode leaf = findLeaf(node.right);
            parents.put(node, leaf);
        }
    }
    if (node.left != null) {
        parents.put(node.left, node);
        dfs(node.left, node, k, parents);
    }
    if (node.right != null) {
        parents.put(node.right, node);
        dfs(node.right, node, k, parents);
    }
}

private static TreeNode findLeaf(TreeNode node) {
    if (isLeaf(node)) {
        return node;
    }
    Queue<TreeNode> q = new LinkedList<>();
    q.offer(node);
    while (!q.isEmpty()) {
        TreeNode n = q.poll();
        if (isLeaf(n)) {
            return n;
        }
        if (n.left != null) {
            q.offer(n.left);
        }
        if (n.right != null) {
            q.offer(n.right);
        }
    }
    throw new IllegalArgumentException("no leaf found");
}
总结

利用深度优先搜索或广度优先搜索,可以找到二叉树中离给定节点最近的叶子节点。在搜索时,我们可以通过递归遍历找到给定节点,并维护每个节点的父节点,以便在遍历过程中查找与给定节点最近的叶子节点。最后,我们可以使用队列遍历整个树,直接找到离给定节点最近的叶子节点。