Open In App

Print all nodes at distance k from a given node

Improve
Improve
Like Article
Like
Save
Share
Report
 

Given a binary tree, a target node in the binary tree, and an integer value k, print all the nodes that are at distance k from the given target node. No parent pointers are available.

BinaryTree

Consider the tree shown in diagram
Input: target = pointer to node with data 8. 
root = pointer to node with data 20. 
k = 2. 
Output : 10 14 22
If target is 14 and k is 3, then output 
should be “4 20”

There are two types of nodes to be considered. 
1) Nodes in the subtree rooted with target node. For example, if the target node is 8 and k is 2, then such nodes are 10 and 14. 
2) Other nodes, may be an ancestor of target, or a node in some other subtree. For target node 8 and k is 2, the node 22 comes in this category.
Finding the first type of nodes is easy to implement. Just traverse subtrees rooted with the target node and decrement k in recursive call. When the k becomes 0, print the node currently being traversed (See this for more details). Here we call the function as printkdistanceNodeDown().
How to find nodes of second type? For the output nodes not lying in the subtree with the target node as the root, we must go through all ancestors. For every ancestor, we find its distance from target node, let the distance be d, now we go to other subtree (if target was found in left subtree, then we go to right subtree and vice versa) of the ancestor and find all nodes at k-d distance from the ancestor.

Following is the implementation of the above approach.  

C++




#include<bits/stdc++.h>
using namespace std;
 
// A binary Tree node
struct Node{
    int data;
    Node* left;
    Node* right;
};
 
// Recursive function to print all the nodes at distance k in the
// tree (or subtree) rooted with given root. See */
void printkdistanceNodeDown(Node* root, int k){
    // Base Case
    if (root == NULL || k < 0) return;
 
    // If we reach a k distant node, print it
    if (k==0){
        cout<< root->data<<endl;
        return;
    }
 
    // Recur for left and right subtrees
    printkdistanceNodeDown(root->left, k-1);
    printkdistanceNodeDown(root->right, k-1);
}
 
// Prints all nodes at distance k from a given target node.
// The k distant nodes may be upward or downward. This function
// Returns distance of root from target node, it returns
// -1 if target node is not present in tree rooted with root.
int printkdistanceNode(Node* root, Node* target , int k){
    // Base Case 1: If tree is empty, return -1
    if (root == NULL) return -1;
 
    // If target is same as root. Use the downward function
    // to print all nodes at distance k in subtree rooted with
    // target or root
    if (root == target){
        printkdistanceNodeDown(root, k);
        return 0;
    }
 
    // Recur for left subtree
    int dl = printkdistanceNode(root->left, target, k);
 
    // Check if target node was found in left subtree
    if (dl != -1){
        // If root is at distance k from target, print root
        // Note that dl is Distance of root's
        // left child from target
        if (dl + 1 == k)
            cout<<root->data<<endl;
 
        // Else go to right subtree and print all k-dl-2
        // distant nodes Note that the right child is 2
        // edges away from left child
        else
            printkdistanceNodeDown(root->right, k-dl-2);
 
        // Add 1 to the distance and return value for parent calls
        return 1 + dl;
    }
 
    // MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
    // Note that we reach here only when node was
    // not found in left subtree
    int dr = printkdistanceNode(root->right, target, k);
    if (dr != -1){
        if (dr + 1 == k)
            cout<<root->data<<endl;
        else
            printkdistanceNodeDown(root->left, k-dr-2);
        return 1 + dr;
    }
 
    // If target was neither present in left
    // nor in right subtree
    return -1;
}
 
// A utility function to create a new binary tree node
Node* newNode(int data){
    Node* temp = new Node();
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
 
// Driver program to test above functions
int main(){
    // Let us construct the tree shown in above diagram
    Node* root = newNode(20);
    root->left = newNode(8);
    root->right = newNode(22);
    root->left->left = newNode(4);
    root->left->right = newNode(12);
    root->left->right->left = newNode(10);
    root->left->right->right = newNode(14);
    Node* target = root->left->right;
    printkdistanceNode(root, target, 2);
    return 0;
}


Java




// Java program to print all nodes at a distance k from given node
 
// A binary tree node
class Node
{
    int data;
    Node left, right;
  
    Node(int item)
    {
        data = item;
        left = right = null;
    }
}
  
class BinaryTree
{
    Node root;
    /* Recursive function to print all the nodes at distance k in
       tree (or subtree) rooted with given root. */
  
    void printkdistanceNodeDown(Node node, int k)
    {
        // Base Case
        if (node == null || k < 0)
            return;
  
        // If we reach a k distant node, print it
        if (k == 0)
        {
            System.out.print(node.data);
            System.out.println("");
            return;
        }
  
        // Recur for left and right subtrees
        printkdistanceNodeDown(node.left, k - 1);
        printkdistanceNodeDown(node.right, k - 1);
    }
  
    // Prints all nodes at distance k from a given target node.
    // The k distant nodes may be upward or downward.This function
    // Returns distance of root from target node, it returns -1
    // if target node is not present in tree rooted with root.
    int printkdistanceNode(Node node, Node target, int k)
    {
        // Base Case 1: If tree is empty, return -1
        if (node == null)
            return -1;
  
        // If target is same as root.  Use the downward function
        // to print all nodes at distance k in subtree rooted with
        // target or root
        if (node == target)
        {
            printkdistanceNodeDown(node, k);
            return 0;
        }
  
        // Recur for left subtree
        int dl = printkdistanceNode(node.left, target, k);
  
        // Check if target node was found in left subtree
        if (dl != -1)
        {
              
            // If root is at distance k from target, print root
            // Note that dl is Distance of root's left child from
            // target
            if (dl + 1 == k)
            {
                System.out.print(node.data);
                System.out.println("");
            }
              
            // Else go to right subtree and print all k-dl-2 distant nodes
            // Note that the right child is 2 edges away from left child
            else
                printkdistanceNodeDown(node.right, k - dl - 2);
  
            // Add 1 to the distance and return value for parent calls
            return 1 + dl;
        }
  
        // MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
        // Note that we reach here only when node was not found in left
        // subtree
        int dr = printkdistanceNode(node.right, target, k);
        if (dr != -1)
        {
            if (dr + 1 == k)
            {
                System.out.print(node.data);
                System.out.println("");
            }
            else
                printkdistanceNodeDown(node.left, k - dr - 2);
            return 1 + dr;
        }
  
        // If target was neither present in left nor in right subtree
        return -1;
    }
  
    // Driver program to test the above functions
    public static void main(String args[])
    {
        BinaryTree tree = new BinaryTree();
  
        /* Let us construct the tree shown in above diagram */
        tree.root = new Node(20);
        tree.root.left = new Node(8);
        tree.root.right = new Node(22);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(12);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(14);
        Node target = tree.root.left.right;
        tree.printkdistanceNode(tree.root, target, 2);
    }
}
  
// This code has been contributed by Mayank Jaiswal


Python3




# Python program to print nodes at distance k from a given node
 
# A binary tree node
class Node:
    # A constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
     
# Recursive function to print all the nodes at distance k
# int the tree(or subtree) rooted with given root. See
def printkDistanceNodeDown(root, k):
     
    # Base Case
    if root is None or k< 0 :
        return
     
    # If we reach a k distant node, print it
    if k == 0 :
        print (root.data)
        return
     
    # Recur for left and right subtree
    printkDistanceNodeDown(root.left, k-1)
    printkDistanceNodeDown(root.right, k-1)
 
 
# Prints all nodes at distance k from a given target node
# The k distant nodes may be upward or downward. This function
# returns distance of root from target node, it returns -1
# if target node is not present in tree rooted with root
def printkDistanceNode(root, target, k):
     
    # Base Case 1 : IF tree is empty return -1
    if root is None:
        return -1
 
    # If target is same as root. Use the downward function
    # to print all nodes at distance k in subtree rooted with
    # target or root
    if root == target:
        printkDistanceNodeDown(root, k)
        return 0
     
    # Recur for left subtree
    dl = printkDistanceNode(root.left, target, k)
     
    # Check if target node was found in left subtree
    if dl != -1:
         
        # If root is at distance k from target, print root
        # Note: dl is distance of root's left child
        # from target
        if dl +1 == k :
            print (root.data)
     
        # Else go to right subtree and print all k-dl-2
        # distant nodes
        # Note: that the right child is 2 edges away from
        # left child
        else:
            printkDistanceNodeDown(root.right, k-dl-2)
 
        # Add 1 to the distance and return value for
        # for parent calls
        return 1 + dl
 
    # MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
    # Note that we reach here only when node was not found
    # in left subtree
    dr = printkDistanceNode(root.right, target, k)
    if dr != -1:
        if (dr+1 == k):
            print (root.data)
        else:
            printkDistanceNodeDown(root.left, k-dr-2)
        return 1 + dr
 
    # If target was neither present in left nor in right subtree
    return -1
 
# Driver program to test above function
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
target = root.left.right
printkDistanceNode(root, target, 2)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)


C#




using System;
 
// C# program to print all nodes at a distance k from given node
 
// A binary tree node
public class Node
{
    public int data;
    public Node left, right;
 
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
 
public class BinaryTree
{
    public Node root;
    /* Recursive function to print all the nodes at distance k in
       tree (or subtree) rooted with given root. */
 
    public virtual void printkdistanceNodeDown(Node node, int k)
    {
        // Base Case
        if (node == null || k < 0)
        {
            return;
        }
 
        // If we reach a k distant node, print it
        if (k == 0)
        {
            Console.Write(node.data);
            Console.WriteLine("");
            return;
        }
 
        // Recur for left and right subtrees
        printkdistanceNodeDown(node.left, k - 1);
        printkdistanceNodeDown(node.right, k - 1);
    }
 
    // Prints all nodes at distance k from a given target node.
    // The k distant nodes may be upward or downward.This function
    // Returns distance of root from target node, it returns -1
    // if target node is not present in tree rooted with root.
    public virtual int printkdistanceNode(Node node, Node target, int k)
    {
        // Base Case 1: If tree is empty, return -1
        if (node == null)
        {
            return -1;
        }
 
        // If target is same as root.  Use the downward function
        // to print all nodes at distance k in subtree rooted with
        // target or root
        if (node == target)
        {
            printkdistanceNodeDown(node, k);
            return 0;
        }
 
        // Recur for left subtree
        int dl = printkdistanceNode(node.left, target, k);
 
        // Check if target node was found in left subtree
        if (dl != -1)
        {
 
            // If root is at distance k from target, print root
            // Note that dl is Distance of root's left child from 
            // target
            if (dl + 1 == k)
            {
                Console.Write(node.data);
                Console.WriteLine("");
            }
 
            // Else go to right subtree and print all k-dl-2 distant nodes
            // Note that the right child is 2 edges away from left child
            else
            {
                printkdistanceNodeDown(node.right, k - dl - 2);
            }
 
            // Add 1 to the distance and return value for parent calls
            return 1 + dl;
        }
 
        // MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
        // Note that we reach here only when node was not found in left 
        // subtree
        int dr = printkdistanceNode(node.right, target, k);
        if (dr != -1)
        {
            if (dr + 1 == k)
            {
                Console.Write(node.data);
                Console.WriteLine("");
            }
            else
            {
                printkdistanceNodeDown(node.left, k - dr - 2);
            }
            return 1 + dr;
        }
 
        // If target was neither present in left nor in right subtree
        return -1;
    }
 
    // Driver program to test the above functions
    public static void Main(string[] args)
    {
        BinaryTree tree = new BinaryTree();
 
        /* Let us construct the tree shown in above diagram */
        tree.root = new Node(20);
        tree.root.left = new Node(8);
        tree.root.right = new Node(22);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(12);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(14);
        Node target = tree.root.left.right;
        tree.printkdistanceNode(tree.root, target, 2);
    }
}
 
// This code is contributed by Shrikant13


Javascript




<script>
 
// Javascript program to print all nodes at a distance k from given node
 
// A binary tree node
class Node
{
    constructor(item)
    {
        this.data = item;
        this.left = null;
        this.right = null;
    }
}
 
var root = null;
 
/* Recursive function to print all the nodes at distance k in
   tree (or subtree) rooted with given root. */
function printkdistanceNodeDown(node, k)
{
    // Base Case
    if (node == null || k < 0)
    {
        return;
    }
    // If we reach a k distant node, print it
    if (k == 0)
    {
        document.write(node.data);
        document.write("<br>");
        return;
    }
    // Recur for left and right subtrees
    printkdistanceNodeDown(node.left, k - 1);
    printkdistanceNodeDown(node.right, k - 1);
}
// Prints all nodes at distance k from a given target node.
// The k distant nodes may be upward or downward.This function
// Returns distance of root from target node, it returns -1
// if target node is not present in tree rooted with root.
function printkdistanceNode(node, target, k)
{
    // Base Case 1: If tree is empty, return -1
    if (node == null)
    {
        return -1;
    }
    // If target is same as root.  Use the downward function
    // to print all nodes at distance k in subtree rooted with
    // target or root
    if (node == target)
    {
        printkdistanceNodeDown(node, k);
        return 0;
    }
    // Recur for left subtree
    var dl = printkdistanceNode(node.left, target, k);
    // Check if target node was found in left subtree
    if (dl != -1)
    {
        // If root is at distance k from target, print root
        // Note that dl is Distance of root's left child from 
        // target
        if (dl + 1 == k)
        {
            document.write(node.data);
            document.write("<br>");
        }
        // Else go to right subtree and print all k-dl-2 distant nodes
        // Note that the right child is 2 edges away from left child
        else
        {
            printkdistanceNodeDown(node.right, k - dl - 2);
        }
        // Add 1 to the distance and return value for parent calls
        return 1 + dl;
    }
    // MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
    // Note that we reach here only when node was not found in left 
    // subtree
    var dr = printkdistanceNode(node.right, target, k);
    if (dr != -1)
    {
        if (dr + 1 == k)
        {
            document.write(node.data);
            document.write("<br>");
        }
        else
        {
            printkdistanceNodeDown(node.left, k - dr - 2);
        }
        return 1 + dr;
    }
    // If target was neither present in left nor in right subtree
    return -1;
}
 
 
// Driver program to test the above functions
 
/* Let us construct the tree shown in above diagram */
root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
var target = root.left.right;
printkdistanceNode(root, target, 2);
 
// This code is contributed by importantly.
</script>


Output

4
20







Time Complexity: At first look the time complexity looks more than O(n), but if we take a closer look, we can observe that no node is traversed more than twice. Therefore the time complexity is O(n).

The space complexity of this program is O(h),

Alternate Solution : 

  1. Get Path from the Root node and add into a list
  2. For each ith element from Path just iterate and print (K-i)th distance nodes.

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int val)
    {
        this->val = val;
        this->left = NULL;
        this->right = NULL;
    }
};
 
// global variable
vector<TreeNode*> path;
 
// finding the path of target node from root node
bool findPath(TreeNode* node, TreeNode* target)
{
    if (node == NULL) {
        return false;
    }
    if (node == target || findPath(node->left, target)
        || findPath(node->right, target)) {
        path.push_back(node);
        return true;
    }
    return false;
}
 
// blocker is used for ancestors node if target at
// left than we have to go in right or if target at right
// then we have to go in left.
void findKDistanceFromNode(TreeNode* node, int dist,
                           vector<int>& result,
                           TreeNode* blocker)
{
    if (dist < 0 || node == NULL
        || (blocker != NULL && node == blocker)) {
        return;
    }
    if (dist == 0) {
        result.push_back(node->val);
    }
 
    findKDistanceFromNode(node->left, dist - 1, result,
                          blocker);
    findKDistanceFromNode(node->right, dist - 1, result,
                          blocker);
}
 
// finding all the nodes at a distance k from target
vector<int> distanceK(TreeNode* root, TreeNode* target,
                      int K)
{
    findPath(root, target);
    vector<int> result;
    for (int i = 0; i < path.size(); i++) {
        findKDistanceFromNode(path[i], K - i, result,
                              i == 0 ? NULL : path[i - 1]);
    }
    // returning list of all nodes at a distance K
    return result;
}
 
// driver program to test the above functions
int main()
{
    TreeNode* root = new TreeNode(20);
    root->left = new TreeNode(8);
    root->right = new TreeNode(22);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(12);
    root->left->right->left = new TreeNode(10);
    root->left->right->right = new TreeNode(4);
    TreeNode* target = root->left->right;
    vector<int> result = distanceK(root, target, 2);
    cout << "[";
    for (int i = 0; i < result.size() - 1; i++) {
        cout << result[i] << ", ";
    }
    cout << result[result.size() - 1] << "]" << endl;
    return 0;
}
 
// this code is contributed by Yash
// Agarwal(yashagarwal2852002)


Java




import java.io.*;
import java.util.*;
 
class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode() {}
 
    public TreeNode(int val) { this.val = val; }
}
 
class GFG {
    List<TreeNode> path = null;
      //Finding all the nodes at a distance K from target
      //node.
    public List<Integer> distanceK(TreeNode root,
                                   TreeNode target, int K)
    {
        path = new ArrayList<>();
        findPath(root, target);
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < path.size(); i++) {
            findKDistanceFromNode(
                path.get(i), K - i, result,
                i == 0 ? null : path.get(i - 1));
        }
          //Returning list of all nodes at a distance K
        return result;
    }
 
    // Blocker is used for ancestors node if target at
      //left then we have to go in right or if target at
      // right then we have to go in left.
    public void findKDistanceFromNode(TreeNode node,
                                      int dist,
                                      List<Integer> result,
                                      TreeNode blocker)
    {
        if (dist < 0 || node == null
            || (blocker != null && node == blocker)) {
            return;
        }
 
        if (dist == 0) {
            result.add(node.val);
        }
 
        findKDistanceFromNode(node.left, dist - 1, result,
                              blocker);
        findKDistanceFromNode(node.right, dist - 1, result,
                              blocker);
    }
    //Finding the path of target node from root node
    public boolean findPath(TreeNode node, TreeNode target)
    {
        if (node == null)
            return false;
 
        if (node == target || findPath(node.left, target)
            || findPath(node.right, target)) {
            path.add(node);
            return true;
        }
 
        return false;
    }
     // Driver program to test the above functions
    public static void main(String[] args)
    {
        GFG gfg = new GFG();
        /* Let us construct the tree shown in above diagram */
        TreeNode root = new TreeNode(20);
        root.left = new TreeNode(8);
        root.right = new TreeNode(22);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(12);
        root.left.right.left = new TreeNode(10);
        root.left.right.right = new TreeNode(14);
        TreeNode target = root.left.right;
        System.out.println(gfg.distanceK(root, target, 2));
    }
}


Python3




class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
 
class GFG:
    path = None
 
    def distanceK(self, root: TreeNode, target: TreeNode, K: int):
        self.path = []
        self.findPath(root, target)
        result = []
        for i in range(len(self.path)):
            self.findKDistanceFromNode(self.path[i], K-i, result, None if i == 0 else self.path[i-1])
        return result
 
    def findKDistanceFromNode(self, node, dist, result, blocker: TreeNode):
        if dist < 0 or node is None or (blocker is not None and node == blocker):
            return
        if dist == 0:
            result.append(node.val)
        self.findKDistanceFromNode(node.left, dist-1, result, blocker)
        self.findKDistanceFromNode(node.right, dist-1, result, blocker)
 
    def findPath(self, node: TreeNode, target: TreeNode) -> bool:
        if node is None:
            return False
        if node == target or self.findPath(node.left, target) or self.findPath(node.right, target):
            self.path.append(node)
            return True
        return False
 
if __name__ == "__main__":
    gfg = GFG()
    root = TreeNode(20)
    root.left = TreeNode(8)
    root.right = TreeNode(22)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(12)
    root.left.right.left = TreeNode(10)
    root.left.right.right = TreeNode(14)
    target = root.left.right
    print(gfg.distanceK(root, target, 2))


C#




using System;
using System.Collections.Generic;
 
// TreeNode class
public class TreeNode
{
    public int val;
    public TreeNode left;
    public TreeNode right;
 
    public TreeNode() {}
 
    public TreeNode(int val)
    {
        this.val = val;
    }
}
 
// GFG class
class GFG
{
    List<TreeNode> path = null;
 
    // Finding all the nodes at a distance K from target node.
    public List<int> DistanceK(TreeNode root, TreeNode target, int K)
    {
        path = new List<TreeNode>();
        FindPath(root, target);
 
        List<int> result = new List<int>();
        for (int i = 0; i < path.Count; i++)
        {
            FindKDistanceFromNode(
                path[i], K - i, result,
                i == 0 ? null : path[i - 1]);
        }
 
        // Returning a list of all nodes at a distance K
        return result;
    }
 
    // Blocker is used for ancestor nodes. If target is at left then we have to go in right
    // or if target is at right then we have to go in left.
    public void FindKDistanceFromNode(TreeNode node, int dist, List<int> result, TreeNode blocker)
    {
        if (dist < 0 || node == null || (blocker != null && node == blocker))
        {
            return;
        }
 
        if (dist == 0)
        {
            result.Add(node.val);
        }
 
        FindKDistanceFromNode(node.left, dist - 1, result, blocker);
        FindKDistanceFromNode(node.right, dist - 1, result, blocker);
    }
 
    // Finding the path of target node from root node.
    public bool FindPath(TreeNode node, TreeNode target)
    {
        if (node == null)
            return false;
 
        if (node == target || FindPath(node.left, target) || FindPath(node.right, target))
        {
            path.Add(node);
            return true;
        }
 
        return false;
    }
 
    // Driver program to test the above functions
    static void Main(string[] args)
    {
        GFG gfg = new GFG();
 
        /* Let us construct the tree shown in above diagram */
        TreeNode root = new TreeNode(20);
        root.left = new TreeNode(8);
        root.right = new TreeNode(22);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(12);
        root.left.right.left = new TreeNode(10);
        root.left.right.right = new TreeNode(14);
 
        TreeNode target = root.left.right;
        Console.WriteLine(string.Join(", ", gfg.DistanceK(root, target, 2)));
    }
}


Javascript




<script>
// JavaScript program for the above approach
class TreeNode{
    constructor(val){
        this.val = val;
        this.left = null;
        this.right = null;
    }
}
 
// global variable
let path = [];
 
// finding the path of target node from root node
function findPath(node, target){
    if(node == null) return false;
     
    if(node == target || findPath(node.left, target)
        || findPath(node.right, target)){
        path.push(node);
        return true;
    }
    return false;
}
 
// blocker is used for ancestors node if target at
// left than we have to go in right or if target at right
// then we have to go in left.
function findKDistanceFromNode(node, dist, result, blocker){
    if(dist < 0 || node == null || (blocker != null && node == blocker)){
        return;
    }
    if(dist == 0)
        result.push(node.val);
     
    findKDistanceFromNode(node.left, dist-1, result, blocker);
    findKDistanceFromNode(node.right, dist-1, result, blocker);
}
 
// finding all the nodes at a distance k from target
function distanceK(root, target, K){
    findPath(root, target);
    let result = [];
    for(let i = 0; i<path.length; i++){
        findKDistanceFromNode(path[i], K-i, result, i == 0 ? null : path[i-1]);
    }
    // returning list of all nodes at a distance k
    return result;
}
 
// driver program to test above functions
let root = new TreeNode(20);
root.left = new TreeNode(8);
root.right = new TreeNode(22);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(12);
root.left.right.left = new TreeNode(10);
root.left.right.right = new TreeNode(4);
let target = root.left.right;
let result = distanceK(root, target, 2);
document.write("[");
for(let i = 0; i<result.length-1; i++){
    document.write(result[i] + ", ");
}
document.write(result[result.length-1] + "]");
 
// THIS CODE IS CONTRIBUTED BY KIRTI AGARWAL(KIRTIAGARWAL23121999)
</script>


Output

[4, 20]







Time complexity: O(n)

Approach Using BFS:-

  • We will be using level order traversal to print nodes

Implementation:-

  • First we will find the target node using level order traversal.
  • While finding the target node we will store the parent of each node so that we can move towards the parent of the node as well.
  • After this we will traverse from the target node to all the three directions that is toward both child and parent till distance K and print the nodes at distance K.

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int val)
    {
        this->val = val;
        this->left = NULL;
        this->right = NULL;
    }
};
 
// finding all the nodes at a distance k from target
vector<int> distanceK(TreeNode* root, TreeNode* target,
                      int K)
{
  //vector to store answer
  vector<int>ans;
   
  //queue for bfs
  queue<TreeNode*> q;
   
  q.push(root);
   
  //to store target node
  TreeNode* need;
   
  //map to store parent of each node
  unordered_map<TreeNode*, TreeNode*> m;
   
  //bfs
  while(q.size()){
     
    int s = q.size();
     
    //traversing to current level
    for(int i=0;i<s;i++){
       
      TreeNode* temp = q.front();
       
      q.pop();
       
      //if target value found
      if(temp==target) need=temp;
       
      if(temp->left){
        q.push(temp->left);
        m[temp->left]=temp;
      }
       
      if(temp->right){
        q.push(temp->right);
        m[temp->right]=temp;
      }
       
    }
     
  }
   
  //map to store occurrence of a node
  //that is the node has taken or not
  unordered_map<TreeNode*, int> mm;
   
  q.push(need);
   
  //to store current distance
  int c = 0;
   
  while(q.size()){
     
    int s = q.size();
     
    for(int i=0;i<s;i++){
       
      TreeNode* temp = q.front();
       
      q.pop();
       
      mm[temp] = 1;
       
      if(c==K)
      ans.push_back(temp->val);
       
      //moving left
      if(temp->left&&mm[temp->left]==0){
        q.push(temp->left);
      }
       
      //moving right
      if(temp->right&&mm[temp->right]==0){
        q.push(temp->right);
      }
       
      //moving to parent
      if(m[temp]&&mm[m[temp]]==0){
        q.push(m[temp]);
      }
       
    }
     
    c++;
    if(c>K)break;
     
  }
  return ans;
}
 
// driver program to test the above functions
int main()
{
    TreeNode* root = new TreeNode(20);
    root->left = new TreeNode(8);
    root->right = new TreeNode(22);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(12);
    root->left->right->left = new TreeNode(10);
    root->left->right->right = new TreeNode(4);
    TreeNode* target = root->left->right;
    vector<int> result = distanceK(root, target, 2);
    cout << "[";
    for (int i = 0; i < result.size() - 1; i++) {
        cout << result[i] << ", ";
    }
    cout << result[result.size() - 1] << "]" << endl;
    return 0;
}
 
// this code is contributed by shubhamrajput6156


Java




// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
// creating tree node
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
 
    public TreeNode(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}
 
public class Main {
 
  // finding all the nodes at a distance k from target
    public static List<Integer> distanceK(TreeNode root, TreeNode target, int K) {
       
      // list for answer storing
        List<Integer> ans = new ArrayList<>();
       
      // Queue for bfs
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
  
        TreeNode need = null;
        
      //map to store parent of each node
        Map<TreeNode, TreeNode> m = new HashMap<>();
 
        while (!q.isEmpty()) {
            int s = q.size();
           
          // traversing the current level
            for (int i = 0; i < s; i++) {
                TreeNode temp = q.poll();
                 
              // if target found then
                if (temp == target) {
                    need = temp;
                }
                 
                if (temp.left != null) {
                    q.offer(temp.left);
                    m.put(temp.left, temp);
                }
                 
                if (temp.right != null) {
                    q.offer(temp.right);
                    m.put(temp.right, temp);
                }
            }
        }
 
   //map to store occurrence of a node
  //that is the node has taken or not
        Map<TreeNode, Integer> mm = new HashMap<>();
        q.offer(need);
        int c = 0;
 
        while (!q.isEmpty()) {
            int s = q.size();
             
            for (int i = 0; i < s; i++) {
                TreeNode temp = q.poll();
                mm.put(temp, 1);
 
                if (c == K) {
                    ans.add(temp.val);
                }
 
              // moving left
                if (temp.left != null && mm.getOrDefault(temp.left, 0) == 0) {
                    q.offer(temp.left);
                }
 
             // moving right
                if (temp.right != null && mm.getOrDefault(temp.right, 0) == 0) {
                    q.offer(temp.right);
                }
 
                if (m.containsKey(temp) && mm.getOrDefault(m.get(temp), 0) == 0) {
                    q.offer(m.get(temp));
                }
            }
 
            c++;
            if (c > K) {
                break;
            }
        }
 
        return ans;
    }
 
    public static void main(String[] args) {
        TreeNode root = new TreeNode(20);
        root.left = new TreeNode(8);
        root.right = new TreeNode(22);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(12);
        root.left.right.left = new TreeNode(10);
        root.left.right.right = new TreeNode(4);
        TreeNode target = root.left.right;
        List<Integer> result = distanceK(root, target, 2);
        System.out.print("[");
        for (int i = 0; i < result.size() - 1; i++) {
            System.out.print(result.get(i) + ", ");
        }
        System.out.println(result.get(result.size() - 1) + "]");
    }
}


Python3




from collections import deque
 
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
 
def distanceK(root, target, K):
    ans = []
    q = deque()
    q.append(root)
    need = None
    m = {}  # to store the parent of each node
     
    # BFS traversal to find the target node and populate the parent map
    while q:
        s = len(q)
        for i in range(s):
            temp = q.popleft()
            if temp == target:
                need = temp  # found the target node
             
            if temp.left:
                q.append(temp.left)
                m[temp.left] = temp  # map the parent of the left child
             
            if temp.right:
                q.append(temp.right)
                m[temp.right] = temp  # map the parent of the right child
     
    mm = {}  # to store whether a node has been visited or not
    q.append(need)
    c = 0  # current distance from the target node
     
    # BFS traversal to find nodes at distance K from the target node
    while q:
        s = len(q)
        for i in range(s):
            temp = q.popleft()
            mm[temp] = 1  # mark the current node as visited
             
            if c == K:
                ans.append(temp.val)  # add the node value to the result if it's at distance K
             
            if temp.left and mm.get(temp.left, 0) == 0:
                q.append(temp.left)  # move left if the left child is not visited
             
            if temp.right and mm.get(temp.right, 0) == 0:
                q.append(temp.right)  # move right if the right child is not visited
             
            if m.get(temp) and mm.get(m[temp], 0) == 0:
                q.append(m[temp])  # move to the parent if the parent is not visited
         
        c += 1
        if c > K:
            break  # break if the current distance exceeds K (no need to go further)
     
    return ans
 
# driver program to test the above functions
if __name__ == "__main__":
    root = TreeNode(20)
    root.left = TreeNode(8)
    root.right = TreeNode(22)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(12)
    root.left.right.left = TreeNode(10)
    root.left.right.right = TreeNode(14)
    target = root.left.right
    result = distanceK(root, target, 2)
    print(result)  # Output: [4, 20]


C#




using System;
using System.Collections.Generic;
 
// Creating tree node
public class TreeNode
{
    public int Val;
    public TreeNode Left;
    public TreeNode Right;
 
    public TreeNode(int val)
    {
        Val = val;
        Left = null;
        Right = null;
    }
}
 
public class MainClass
{
    // Finding all the nodes at a distance k from target
    public static List<int> DistanceK(TreeNode root, TreeNode target, int K)
    {
        // List for answer storing
        List<int> ans = new List<int>();
 
        // Queue for BFS
        Queue<TreeNode> q = new Queue<TreeNode>();
        q.Enqueue(root);
 
        TreeNode need = null;
 
        // Dictionary to store parent of each node
        Dictionary<TreeNode, TreeNode> m = new Dictionary<TreeNode, TreeNode>();
 
        while (q.Count > 0)
        {
            int s = q.Count;
 
            // Traversing the current level
            for (int i = 0; i < s; i++)
            {
                TreeNode temp = q.Dequeue();
 
                // If target found then
                if (temp == target)
                {
                    need = temp;
                }
 
                if (temp.Left != null)
                {
                    q.Enqueue(temp.Left);
                    m[temp.Left] = temp;
                }
 
                if (temp.Right != null)
                {
                    q.Enqueue(temp.Right);
                    m[temp.Right] = temp;
                }
            }
        }
 
        // Dictionary to store occurrence of a node
        // that is, the node has been visited or not
        Dictionary<TreeNode, int> mm = new Dictionary<TreeNode, int>();
        q.Enqueue(need);
        int c = 0;
 
        while (q.Count > 0)
        {
            int s = q.Count;
 
            for (int i = 0; i < s; i++)
            {
                TreeNode temp = q.Dequeue();
                mm[temp] = 1;
 
                if (c == K)
                {
                    ans.Add(temp.Val);
                }
 
                // Moving left
                if (temp.Left != null && mm.GetValueOrDefault(temp.Left, 0) == 0)
                {
                    q.Enqueue(temp.Left);
                }
 
                // Moving right
                if (temp.Right != null && mm.GetValueOrDefault(temp.Right, 0) == 0)
                {
                    q.Enqueue(temp.Right);
                }
 
                if (m.ContainsKey(temp) && mm.GetValueOrDefault(m[temp], 0) == 0)
                {
                    q.Enqueue(m[temp]);
                }
            }
 
            c++;
            if (c > K)
            {
                break;
            }
        }
 
        return ans;
    }
 
    public static void Main(string[] args)
    {
        TreeNode root = new TreeNode(20);
        root.Left = new TreeNode(8);
        root.Right = new TreeNode(22);
        root.Left.Left = new TreeNode(4);
        root.Left.Right = new TreeNode(12);
        root.Left.Right.Left = new TreeNode(10);
        root.Left.Right.Right = new TreeNode(14);
        TreeNode target = root.Left.Right;
        List<int> result = DistanceK(root, target, 2);
        Console.Write("[");
        for (int i = 0; i < result.Count - 1; i++)
        {
            Console.Write(result[i] + ", ");
        }
        Console.WriteLine(result[result.Count - 1] + "]");
    }
}


Javascript




// JavaScript Program for the above approach
// A binary tree node structure
class TreeNode {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}
 
// finding all the nodes at a distance k from target
function distanceK(root, target, K) {
    // vector to store answer
    let ans = [];
   
    // queue for bfs
    let q = [];
   
    q.push(root);
   
    // to store target node
    let need;
   
    // map to store parent of each node
    let m = new Map();
   
    // bfs
    while (q.length) {
        let s = q.length;
     
        // traversing the current level
        for (let i = 0; i < s; i++) {
            let temp = q.shift();
       
            // if target value found
            if (temp === target) {
                need = temp;
            }
       
            if (temp.left) {
                q.push(temp.left);
                m.set(temp.left, temp);
            }
       
            if (temp.right) {
                q.push(temp.right);
                m.set(temp.right, temp);
            }
        }
    }
   
    // map to store occurrence of a node
    // that is whether the node has been taken or not
    let mm = new Map();
   
    q.push(need);
   
    // to store current distance
    let c = 0;
   
    while (q.length) {
        let s = q.length;
     
        for (let i = 0; i < s; i++) {
            let temp = q.shift();
       
            mm.set(temp, 1);
       
            if (c === K) {
                ans.push(temp.val);
            }
       
            // moving left
            if (temp.left && !mm.has(temp.left)) {
                q.push(temp.left);
            }
       
            // moving right
            if (temp.right && !mm.has(temp.right)) {
                q.push(temp.right);
            }
       
            // moving to parent
            if (m.get(temp) && !mm.has(m.get(temp))) {
                q.push(m.get(temp));
            }
        }
     
        c++;
        if (c > K) {
            break;
        }
    }
   
    return ans;
}
 
// driver program to test the above functions
let root = new TreeNode(20);
root.left = new TreeNode(8);
root.right = new TreeNode(22);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(12);
root.left.right.left = new TreeNode(10);
root.left.right.right = new TreeNode(14);
let target = root.left.right;
let result = distanceK(root, target, 2);
console.log(result);
// THIS CODE IS CONTRIBUTED BY YASH AGARWAL(YASHAGARWAL2852002)


Output

[4, 20]







Time Complexity:- O(N)
Space Complexity:- O(N)



Last Updated : 05 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads