Skip to main content
Back to problems
#863
Medium Algorithms

All nodes distance k in binary tree

Hash Table Tree Depth-First Search Breadth-First Search Binary Tree
67.4% acceptance
Feb 27, 2026
12063
275
Given the root of a binary tree, the value of a target node target, and an integer k, return an array of the values of all nodes that have a distance k from the target node. You can return the answer in any order.

Solution

Rust
Time O(n²)
Space O(n)
LeetCode
solution.rs
/*
 * Given the root of a binary tree, the value of a target node target, and an integer k, return an array of the values of all nodes that have a distance k from the target node.
 * You can return the answer in any order.
 * Example 1:
 * Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2
 * Output: [7,4,1]
 * Explanation: The nodes that are a distance 2 from the target node (with value 5) have values 7, 4, and 1.
 * Example 2:
 * Input: root = [1], target = 1, k = 3
 * Output: []
 * Constraints:
 * The number of nodes in the tree is in the range [1, 500].
 * 0 <= Node.val <= 500
 * All the values Node.val are unique.
 * target is the value of one of the nodes in the tree.
 * 0 <= k <= 1000
 */

use std::collections::{HashMap, HashSet, VecDeque};
use std::rc::Rc;
use std::cell::RefCell;
impl Solution {
  pub fn distance_k(root: Option<Rc<RefCell<TreeNode>>>, target: Option<Rc<RefCell<TreeNode>>>, k: i32) -> Vec<i32> {
    fn build_adj(node: &Option<Rc<RefCell<TreeNode>>>, adj: &mut HashMap<i32, Vec<i32>>) {
      if let Some(n) = node {
        let nb = n.borrow();
        if let Some(l) = &nb.left {
          let lv = l.borrow().val;
          adj.entry(nb.val).or_default().push(lv);
          adj.entry(lv).or_default().push(nb.val);
          build_adj(&nb.left, adj);
        }
        if let Some(r) = &nb.right {
          let rv = r.borrow().val;
          adj.entry(nb.val).or_default().push(rv);
          adj.entry(rv).or_default().push(nb.val);
          build_adj(&nb.right, adj);
        }
      }
    }
    let mut adj: HashMap<i32, Vec<i32>> = HashMap::new();
    build_adj(&root, &mut adj);
    let target_val = target.unwrap().borrow().val;
    let mut visited: HashSet<i32> = HashSet::new();
    visited.insert(target_val);
    let mut queue: VecDeque<(i32, i32)> = VecDeque::new();
    queue.push_back((target_val, 0));
    let mut ans = vec![];
    while let Some((node, dist)) = queue.pop_front() {
      if dist == k { ans.push(node); continue; }
      if dist > k { break; }
      for &neighbor in adj.get(&node).unwrap_or(&vec![]) {
        if visited.insert(neighbor) {
          queue.push_back((neighbor, dist + 1));
        }
      }
    }
    ans
  }
}