leetcode
leetcode 651 ~ 700
二叉树最近的叶节点

二叉树最近的叶节点

难度:

标签:

题目描述

代码结果

运行时间: 34 ms, 内存: 17.2 MB


/*
 * Problem: Find the closest leaf node in a binary tree.
 * Approach: 
 * 1. Use a modified BFS approach utilizing Java Streams. 
 * 2. Traverse the tree level by level. 
 * 3. If a leaf node is found, return its value. 
 */

import java.util.*;
import java.util.stream.*;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class ClosestLeafInBinaryTreeStream {
    public int findClosestLeaf(TreeNode root) {
        if (root == null) return -1;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            List<TreeNode> level = new ArrayList<>();
            while (!queue.isEmpty()) {
                level.add(queue.poll());
            }
            for (TreeNode node : level) {
                if (node.left == null && node.right == null) {
                    return node.val;  // Found a leaf node
                }
            }
            queue.addAll(level.stream()
                               .flatMap(n -> Stream.of(n.left, n.right))
                               .filter(Objects::nonNull)
                               .collect(Collectors.toList()));
        }
        return -1;  // In case no leaf node is found
    }
}

解释

方法:

这个题解的思路是先通过 DFS 找到值为 k 的节点作为起点,同时在 DFS 过程中为每个节点记录其父节点。然后从起点开始进行 BFS 搜索,第一个遇到的叶子节点即为离起点最近的叶子节点。在 BFS 的过程中需要记录已访问过的节点避免重复访问。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在执行DFS时,除了寻找值为k的节点,还需要记录每个节点的父节点?
在执行DFS找到值为k的节点后,记录每个节点的父节点是为了之后的BFS搜索能够从找到的节点向其父节点方向扩展,确保能够探索所有可能的路径以找到最近的叶节点。由于二叉树结构只允许从父节点到子节点的单向访问,没有记录父节点信息将无法从子节点回溯到父节点,限制了搜索的完整性。
🦆
在BFS阶段,如何保证从起点开始搜索到的第一个叶节点是最近的叶节点?
BFS(广度优先搜索)按照从近到远的顺序访问节点,即它首先访问距起始点最近的节点。在此算法中,BFS从找到的起点k开始,依次检查节点的所有相邻节点(子节点和父节点),并将它们加入队列。第一个在BFS过程中遇到的叶节点自然是从起点到达的最近叶节点,因为BFS保证了最先访问所有更接近的非叶节点。
🦆
如果树中存在多个值为k的节点,这个算法如何处理?会找到哪一个?
此算法在DFS过程中将停止于首次发现的值为k的节点,并将其设为起点。因此,如果树中有多个节点的值为k,算法只会处理并从第一个找到的这样的节点开始BFS搜索。这意味着搜索结果可能依赖于节点值k在树中出现的顺序和DFS的遍历顺序。
🦆
在BFS中使用队列时,将节点加入队列前进行的`nxt not in vis and nxt`检查是基于什么考虑?
在BFS中,`nxt not in vis and nxt`检查确保了两件事:首先,`nxt not in vis`确保不会重复访问已经访问过的节点,这是防止无限循环并保证效率的关键;其次,`nxt`检查确保只有存在(非空)的节点被加入到队列中,避免了对空(None)节点的无效操作。这两个检查是为了确保BFS的正确性和效率。

相关问题