Open In App

Path from the root node to a given node in an N-ary Tree

Last Updated : 17 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer N and an N-ary Tree of the following form: 

  • Every node is numbered sequentially, starting from 1, till the last level, which contains the node N.
  • The nodes at every odd level contains 2 children and nodes at every even level contains 4 children.

The task is to print the path from the root node to the node N

Examples:
 

Input: N = 14 
 

Output: 1 2 5 14 
Explanation: The path from node 1 to node 14 is 1 – > 2 – > 5 – > 14.

Input: N = 11 
Output: 1 3 11 
Explanation: The path from node 1 to node 11 is 1 – > 3 – > 11.

Approach: Follow the steps below to solve the problem:

  • Initialize an array to store the number of nodes present in each level of the Tree, i.e. {1, 2, 8, 16, 64, 128 ….} and store it.
  • Calculate prefix sum of the array i.e. {1 3 11 27 91 219 …….}
  • Find the index ind in the prefix sum array which exceeds or is equal to N using lower_bound(). Therefore, ind indicates the number of levels that need to be traversed to reach node N.
  • Initialize a variable say, temp = N and an array path[] to store the nodes from root to N.
  • Decrement ind until it is less than or equal to 1 and keep updating val = temp – prefix[ind – 1].
  • Update temp = prefix[ind – 2] + (val + 1) / 2 if ind is odd.
  • Otherwise, update temp = prefix[ind – 2] + (val + 3) / 4 if ind is even.
  • Append temp into the path[] array.
  • Finally, print the array, path[].

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
// Function to find the path
// from root to N
void PrintPathNodes(ll N)
{
 
    // Stores the number of
    // nodes at (i + 1)-th level
    vector<ll> arr;
    arr.push_back(1);
 
    // Stores the number of nodes
    ll k = 1;
 
    // Stores if the current
    // level is even or odd
    bool flag = true;
 
    while (k < N) {
 
        // If level is odd
        if (flag == true) {
            k *= 2;
            flag = false;
        }
 
        // If level is even
        else {
 
            k *= 4;
            flag = true;
        }
 
        // If level with
        // node N is reached
        if (k > N) {
            break;
        }
 
        // Push into vector
        arr.push_back(k);
    }
 
    ll len = arr.size();
    vector<ll> prefix(len);
    prefix[0] = 1;
 
    // Compute prefix sums of count
    // of nodes in each level
    for (ll i = 1; i < len; ++i) {
        prefix[i] = arr[i] + prefix[i - 1];
    }
 
    vector<ll>::iterator it
        = lower_bound(prefix.begin(),
                      prefix.end(), N);
 
    // Stores the level in which
    // node N s present
    ll ind = it - prefix.begin();
 
    ll temp = N;
 
    // Store path
    vector<int> path;
 
    path.push_back(N);
 
    while (ind > 1) {
        ll val = temp - prefix[ind - 1];
 
        if (ind % 2 != 0) {
            temp = prefix[ind - 2]
                   + (val + 1) / 2;
        }
        else {
            temp = prefix[ind - 2]
                   + (val + 3) / 4;
        }
        --ind;
 
        // Insert temp into path
        path.push_back(temp);
    }
 
    if (N != 1)
        path.push_back(1);
 
    // Print path
    for (int i = path.size() - 1;
         i >= 0; i--) {
 
        cout << path[i] << " ";
    }
}
 
// Driver Code
int main()
{
 
    ll N = 14;
 
    // Function Call
    PrintPathNodes(N);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
public class Main {
    // Function to find the path
    // from root to N
    static void PrintPathNodes(long N)
    {
        // Stores the number of
        // nodes at (i + 1)-th level
        ArrayList<Long> arr = new ArrayList<>();
        arr.add((long)1);
     
        // Stores the number of nodes
        long k = 1;
     
        // Stores if the current
        // level is even or odd
        boolean flag = true;
     
        while (k < N) {
     
            // If level is odd
            if (flag == true) {
                k *= 2;
                flag = false;
            }
     
            // If level is even
            else {
     
                k *= 4;
                flag = true;
            }
     
            // If level with
            // node N is reached
            if (k > N) {
                break;
            }
     
            // Push into array
            arr.add(k);
        }
     
        long len = arr.size();
        ArrayList<Long> prefix = new ArrayList<>();
        prefix.add((long)1);
     
        // Compute prefix sums of count
        // of nodes in each level
        for (long i = 1; i < len; ++i) {
            prefix.add(arr.get((int)i) + prefix.get((int)i - 1));
        }
     
        int ind = Collections.binarySearch(prefix, N);
     
        // Stores the level in which
        // node N s present
        if (ind < 0) {
            ind = -ind - 1;
        }
     
        long temp = N;
     
        // Store path
        ArrayList<Long> path = new ArrayList<>();
        path.add(N);
     
        while (ind > 1) {
            long val = temp - prefix.get((int)ind - 1);
     
            if (ind % 2 != 0) {
                temp = prefix.get((int)ind - 2)
                       + (val + 1) / 2;
            }
            else {
                temp = prefix.get((int)ind - 2)
                       + (val + 3) / 4;
            }
            --ind;
     
            // Insert temp into path
            path.add(temp);
        }
     
        if (N != 1)
            path.add((long)1);
     
        // Print path
        for (int i = path.size() - 1;
             i >= 0; i--) {
     
            System.out.print(path.get(i) + " ");
        }
    }
     
    // Driver Code
    public static void main(String[] args)
    {
        long N = 14;
     
        // Function Call
        PrintPathNodes(N);
    }
}
 
// This code is contributed by princekumaras


Python3




# Python3 program for the above approach
from bisect import bisect_left
 
# Function to find the path
# from root to N
def PrintPathNodes(N):
 
    # Stores the number of
    # nodes at (i + 1)-th level
    arr = []
    arr.append(1)
 
    # Stores the number of nodes
    k = 1
 
    # Stores if the current
    # level is even or odd
    flag = True
    while (k < N):
 
        # If level is odd
        if (flag == True):
            k *= 2
            flag = False
 
        # If level is even
        else:
            k *= 4
            flag = True
 
        # If level with
        # node N is reached
        if (k > N):
            break
 
        # Push into vector
        arr.append(k)
    lenn = len(arr)
    prefix = [0]*(lenn)
    prefix[0] = 1
 
    # Compute prefix sums of count
    # of nodes in each level
    for i in range(1,lenn):
        prefix[i] = arr[i] + prefix[i - 1]
    it = bisect_left(prefix, N)
 
    # Stores the level in which
    # node N s present
    ind = it
    temp = N
 
    # Store path
    path = []
    path.append(N)
    while (ind > 1):
        val = temp - prefix[ind - 1]
 
        if (ind % 2 != 0):
            temp = prefix[ind - 2] + (val + 1) // 2
        else:
            temp = prefix[ind - 2] + (val + 3) // 4
        ind -= 1
 
        # Insert temp into path
        path.append(temp)
    if (N != 1):
        path.append(1)
 
    # Print path
    for i in range(len(path)-1, -1, -1):
        print(path[i], end=" ")
 
# Driver Code
if __name__ == '__main__':
    N = 14
 
    # Function Call
    PrintPathNodes(N)
 
    # This code is contributed by mohit kumar 29


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
  // Function to find the path
  // from root to N
  static void PrintPathNodes(long N)
  {
 
    // Stores the number of
    // nodes at (i + 1)-th level
    List<long> arr = new List<long>();
    arr.Add((long)1);
 
    // Stores the number of nodes
    long k = 1;
 
    // Stores if the current
    // level is even or odd
    bool flag = true;
 
    while (k < N) {
 
      // If level is odd
      if (flag == true) {
        k *= 2;
        flag = false;
      }
 
      // If level is even
      else {
 
        k *= 4;
        flag = true;
      }
 
      // If level with
      // node N is reached
      if (k > N) {
        break;
      }
 
      // Push into array
      arr.Add(k);
    }
 
    long len = arr.Count;
    List<long> prefix = new List<long>();
    prefix.Add((long)1);
 
    // Compute prefix sums of count
    // of nodes in each level
    for (long i = 1; i < len; ++i) {
      prefix.Add(arr[(int)i] + prefix[(int)i - 1]);
    }
 
    int ind = prefix.BinarySearch(N);
 
    // Stores the level in which
    // node N s present
    if (ind < 0) {
      ind = -ind - 1;
    }
 
    long temp = N;
 
    // Store path
    List<long> path = new List<long>();
    path.Add(N);
 
    while (ind > 1) {
      long val = temp - prefix[(int)ind - 1];
 
      if (ind % 2 != 0) {
        temp = prefix[(int)ind - 2] + (val + 1) / 2;
      }
      else {
        temp = prefix[(int)ind - 2] + (val + 3) / 4;
      }
      --ind;
 
      // Insert temp into path
      path.Add(temp);
    }
 
    if (N != 1)
      path.Add((long)1);
 
    // Print path
    for (int i = path.Count - 1; i >= 0; i--) {
 
      Console.Write(path[i] + " ");
    }
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    long N = 14;
 
    // Function Call
    PrintPathNodes(N);
  }
}
 
// This code is contributed by phasing17


Javascript




// JavaScript program for the above approach
function bisect_left(a, x, lo = 0, hi = a.length) {
    while (lo < hi) {
        let mid = Math.floor((lo + hi) / 2);
        if (a[mid] < x) {
            lo = mid + 1;
        } else {
            hi = mid;
        }
    }
    return lo;
}
 
 
// Function to find the path
// from root to N
function PrintPathNodes(N) {
 
 
    // Stores the number of
    // nodes at (i + 1)-th level
    let arr = [];
    arr.push(1);
 
    // Stores the number of nodes
    let k = 1;
 
    // Stores if the current
    // level is even or odd
    let flag = true;
    while (k < N) {
 
        // If level is odd
        if (flag === true) {
            k *= 2;
            flag = false;
        }
 
        // If level is even
        else {
            k *= 4;
            flag = true;
        }
 
        // If level with
        // node N is reached
        if (k > N) {
            break;
        }
 
        // Push into array
        arr.push(k);
    }
    let lenn = arr.length;
    let prefix = new Array(lenn).fill(0);
    prefix[0] = 1;
 
    // Compute prefix sums of count
    // of nodes in each level
    for (let i = 1; i < lenn; i++) {
        prefix[i] = arr[i] + prefix[i - 1];
    }
    let it = bisect_left(prefix, N);
 
    // Stores the level in which
    // node N s present
    let ind = it;
    let temp = N;
 
    // Store path
    let path = [];
    path.push(N);
    while (ind > 1) {
        let val = temp - prefix[ind - 1];
 
        if (ind % 2 !== 0) {
            temp = prefix[ind - 2] + Math.floor((val + 1) / 2);
        } else {
            temp = prefix[ind - 2] + Math.floor((val + 3) / 4);
        }
        ind -= 1;
 
        // Insert temp into path
        path.push(temp);
    }
    if (N !== 1) {
        path.push(1);
    }
 
    // Print path
    for (let i = path.length - 1; i >= 0; i--) {
        process.stdout.write(path[i] + " ");
    }
 
}
 
// Driver Code
let N = 14;
 
// Function Call
PrintPathNodes(N);
 
// This code is contributed by phasing17


Output: 

1 2 5 14

 

Time Complexity: O(log(N))
Auxiliary Space: O(log(N))



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads