Open in App
Not now

# Check whether the given node is in the path between the nodes U and V

• Difficulty Level : Hard
• Last Updated : 01 Nov, 2021

Given three vertices U, V and R of a binary tree, the task is to check whether R lies in the path between U and V. If it is not present in the path then print No otherwise print Yes.
Examples:

Input: U = 4, V = 6, R = 2

Output: Yes
Path 4 -> 2 -> 1 -> 3 -> 6 contains 2
Input: U = 4, V = 6, R = 5

Output: No
Path 4 -> 2 -> 1 -> 3 -> 6 does not contain 5

Approach: The idea is to use Lowest Common Ancestor of two nodes. There are following cases for R to exist in the path between U and V

1. R is the lowest common ancestor of U and V.
2. R is in the left subtree of the lowest common ancestor of U and V and is above V.
3. R is in the right subtree of the lowest common ancestor of U and V and is above U.

To know more about the lowest common ancestor, read the post here.
Below is the implementation of the above approach:

## C++

 `// CPP Program to implement the above approach` `#include ` `using` `namespace` `std;`   `// Table for storing 2^ith parent` `vector> table;`   `// Variable to store the height of the tree` `int` `height;`   `// Graph` `vector> Graph;`   `// Arrays to mark start and end time for a node` `vector<``int``> timeIn, timeOut;`   `// Timer` `int` `cnt_time;`   `// constructor for initializing` `// the global variables` `void` `initialise(``int` `n)` `{`   `  ``// log(n) with base 2` `  ``height = (``int``)``ceil``(log2(n));`   `  ``// Filling with -1 as initial` `  ``table.resize(n + 1, vector<``int``>(height + 1, -1));`   `  ``// Fill the graph with empty lists` `  ``Graph.resize(n + 1);` `  ``timeIn.resize(n + 1);` `  ``timeOut.resize(n + 1);` `  ``cnt_time = 0;` `}`   `// Dfs for pre-processing sparse table and` `// calculating start and end time` `void` `dfs(``int` `s, ``int` `p)` `{`   `  ``// Parent at 1 node distance is always` `  ``// it's direct parent` `  ``table[s][0] = p;`   `  ``// Start time noted` `  ``timeIn[s] = ++cnt_time;`   `  ``// Filling sparse table recursively` `  ``for` `(``int` `i = 1; i <= height; i++)` `    ``table[s][i] = table[table[s][i - 1]][i - 1];`   `  ``// Traversing children of source` `  ``for` `(``int` `child : Graph[s]) {` `    ``if` `(child == p) ``continue``;` `    ``dfs(child, s);` `  ``}`   `  ``// End time noted` `  ``timeOut[s] = ++cnt_time;` `}`   `// Helper function to check lowest common Ancestor` `bool` `check(``int` `u, ``int` `v)` `{` `  ``return` `timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];` `}`   `// Function to return Lowest Common Ancestor of U and V` `int` `lowestCommonAncestor(``int` `U, ``int` `V)` `{` `  ``if` `(check(U, V)) ``return` `U;`   `  ``if` `(check(V, U)) ``return` `V;`   `  ``for` `(``int` `i = height; i >= 0; i--)` `  ``{` `    ``if` `(!check(table[U][i], V)) U = table[U][i];` `  ``}`   `  ``return` `table[U][0];` `}`   `// Function that return true if R` `// exists on the path between U` `// and V in the given tree` `bool` `isPresent(``int` `U, ``int` `V, ``int` `R) ` `{`   `  ``// Dfs` `  ``dfs(1, 1);`   `  ``// Calculating LCA between U and V` `  ``int` `LCA = lowestCommonAncestor(U, V);`   `  ``// Calculating LCA between U and R` `  ``int` `LCA_1 = lowestCommonAncestor(U, R);`   `  ``// Calculating LCA between U and V` `  ``int` `LCA_2 = lowestCommonAncestor(V, R);`   `  ``if` `(LCA == R || (LCA_1 == LCA && LCA_2 == R) ||` `      ``(LCA_2 == LCA && LCA_1 == R)) {` `    ``return` `true``;` `  ``}` `  ``return` `false``;` `}`   `// Driver code` `int` `main(``int` `argc, ``char` `const` `*argv[]) ` `{`   `  ``// Number of vertices` `  ``int` `n = 6;` `  ``initialise(n);`   `  ``// Create the graph` `  ``Graph[1].push_back(2);` `  ``Graph[2].push_back(1);` `  ``Graph[1].push_back(3);` `  ``Graph[3].push_back(1);` `  ``Graph[2].push_back(4);` `  ``Graph[4].push_back(2);` `  ``Graph[2].push_back(5);` `  ``Graph[5].push_back(2);` `  ``Graph[3].push_back(6);` `  ``Graph[6].push_back(3);`   `  ``int` `U = 4, V = 6, R = 2;` `  ``if` `(isPresent(U, V, R))` `    ``cout << ``"Yes"` `<< endl;` `  ``else` `    ``cout << ``"No"` `<< endl;` `}`   `// This code is contributed by sanjeev2552`

## Java

 `// Java implementation of the approach` `import` `java.util.*;`   `class` `GfG {`   `    ``// Table for storing 2^ith parent` `    ``private` `static` `int` `table[][];`   `    ``// Variable to store the height of the tree` `    ``private` `static` `int` `height;`   `    ``// Graph` `    ``private` `static` `ArrayList > Graph;`   `    ``// Arrays to mark start and end time for a node` `    ``private` `static` `int` `timeIn[];` `    ``private` `static` `int` `timeOut[];`   `    ``// Timer` `    ``private` `static` `int` `time;`   `    ``// Private constructor for initializing` `    ``// the global variables` `    ``private` `GfG(``int` `n)` `    ``{`   `        ``// log(n) with base 2` `        ``height = (``int``)Math.ceil(Math.log10(n) / Math.log10(``2``));` `        ``table = ``new` `int``[n + ``1``][height + ``1``];`   `        ``// Fill the graph with empty lists` `        ``Graph = ``new` `ArrayList >();` `        ``for` `(``int` `i = ``0``; i <= n; i++)` `            ``Graph.add(``new` `ArrayList());` `        ``timeIn = ``new` `int``[n + ``1``];` `        ``timeOut = ``new` `int``[n + ``1``];` `        ``time = ``0``;` `    ``}`   `    ``// Filling with -1 as initial` `    ``private` `static` `void` `preprocessing(``int` `n)` `    ``{` `        ``for` `(``int` `i = ``0``; i < n + ``1``; i++) {` `            ``Arrays.fill(table[i], -``1``);` `        ``}` `    ``}`   `    ``// Dfs for pre-processing sparse table and` `    ``// calculating start and end time` `    ``private` `static` `void` `dfs(``int` `s, ``int` `p)` `    ``{` `        ``// Parent at 1 node distance is always` `        ``// it's direct parent` `        ``table[s][``0``] = p;`   `        ``// Start time noted` `        ``timeIn[s] = ++time;`   `        ``// Filling sparse table recursively` `        ``for` `(``int` `i = ``1``; i <= height; i++)` `            ``table[s][i] = table[table[s][i - ``1``]][i - ``1``];`   `        ``// Traversing children of source` `        ``for` `(``int` `child : Graph.get(s)) {` `            ``if` `(child == p)` `                ``continue``;` `            ``dfs(child, s);` `        ``}`   `        ``// End time noted` `        ``timeOut[s] = ++time;` `    ``}`   `    ``// Helper function to check lowest common Ancestor` `    ``private` `static` `boolean` `check(``int` `u, ``int` `v)` `    ``{` `        ``return` `timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];` `    ``}`   `    ``// Function to return Lowest Common Ancestor of U and V` `    ``private` `static` `int` `lowestCommonAncestor(``int` `U, ``int` `V)` `    ``{` `        ``if` `(check(U, V))` `            ``return` `U;`   `        ``if` `(check(V, U))` `            ``return` `V;`   `        ``for` `(``int` `i = height; i >= ``0``; i--) {` `            ``if` `(!check(table[U][i], V))` `                ``U = table[U][i];` `        ``}`   `        ``return` `table[U][``0``];` `    ``}`   `    ``// Function that return true if R` `    ``// exists on the path between U` `    ``// and V in the given tree` `    ``private` `static` `boolean` `isPresent(``int` `U, ``int` `V, ``int` `R)` `    ``{`   `        ``// Dfs` `        ``dfs(``1``, ``1``);`   `        ``// Calculating LCA between U and V` `        ``int` `LCA = lowestCommonAncestor(U, V);`   `        ``// Calculating LCA between U and R` `        ``int` `LCA_1 = lowestCommonAncestor(U, R);`   `        ``// Calculating LCA between U and V` `        ``int` `LCA_2 = lowestCommonAncestor(V, R);`   `        ``if` `(LCA == R || (LCA_1 == LCA && LCA_2 == R)` `            ``|| (LCA_2 == LCA && LCA_1 == R)) {` `            ``return` `true``;` `        ``}` `        ``return` `false``;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `main(String args[])` `    ``{` `        ``// Number of vertices` `        ``int` `n = ``6``;` `        ``GfG obj = ``new` `GfG(n);`   `        ``// Create the graph` `        ``preprocessing(n);` `        ``Graph.get(``1``).add(``2``);` `        ``Graph.get(``2``).add(``1``);` `        ``Graph.get(``1``).add(``3``);` `        ``Graph.get(``3``).add(``1``);` `        ``Graph.get(``2``).add(``4``);` `        ``Graph.get(``4``).add(``2``);` `        ``Graph.get(``2``).add(``5``);` `        ``Graph.get(``5``).add(``2``);` `        ``Graph.get(``3``).add(``6``);` `        ``Graph.get(``6``).add(``3``);`   `        ``int` `U = ``4``, V = ``6``, R = ``2``;` `        ``if` `(isPresent(U, V, R))` `            ``System.out.print(``"Yes"``);` `        ``else` `            ``System.out.print(``"No"``);` `    ``}` `}`

## Python3

 `# Python3 implementation of the approach` `import` `math`   `n ``=` `6`   `# Graph` `Graph ``=` `[]`   `# log(n) with base 2` `height ``=` `math.ceil(math.log10(n) ``/` `math.log10(``2``))` `table ``=` `[[``-``1` `for` `i ``in` `range``(n ``+` `1``)] ``for` `j ``in` `range``(n ``+` `1``)]`   `# Fill the graph with empty lists` `for` `i ``in` `range``(n ``+` `1``):` `  ``Graph.append([])` `timeIn ``=` `[``0``]``*``(n ``+` `1``)` `timeOut ``=` `[``0``]``*``(n ``+` `1``)` `time ``=` `0`   `# Filling with -1 as initial` `def` `preprocessing(n):` `    ``for` `i ``in` `range``(n ``+` `1``):` `        ``for` `j ``in` `range``(height ``+` `1``):` `            ``table[i][j] ``=` `-``1`   `# Dfs for pre-processing sparse table and` `# calculating start and end time` `def` `dfs(s, p):` `    ``global` `time` `    ``# Parent at 1 node distance is always` `    ``# it's direct parent` `    ``table[s][``0``] ``=` `p` `    `  `    ``# Start time noted` `    ``timeIn[s] ``=` `time``+``1`   `    ``# Filling sparse table recursively` `    ``for` `i ``in` `range``(``1``, height ``+` `1``):` `        ``table[s][i] ``=` `table[table[s][i ``-` `1``]][i ``-` `1``]`   `    ``# Traversing children of source` `    ``for` `child ``in` `range``(``len``(Graph[s])):` `        ``if` `Graph[s][child] ``=``=` `p:` `            ``continue` `        ``dfs(Graph[s][child], s)`   `    ``# End time noted` `    ``time``+``=``1` `    ``timeOut[s] ``=` `time`   `# Helper function to check lowest common Ancestor` `def` `check(u, v):` `    ``return` `(timeIn[u] <``=` `timeIn[v] ``and` `timeOut[u] >``=` `timeOut[v])`   `# Function to return Lowest Common Ancestor of U and V` `def` `lowestCommonAncestor(U, V):` `    ``if` `check(U, V):` `        ``return` `U`   `    ``if` `check(V, U):` `        ``return` `V`   `    ``for` `i ``in` `range``(height, ``-``1``, ``-``1``):` `        ``if` `not` `check(table[U][i], V):` `            ``U ``=` `table[U][i]`   `    ``return` `table[U][``0``]`   `# Function that return true if R` `# exists on the path between U` `# and V in the given tree` `def` `isPresent(U, V, R):` `    ``# Dfs` `    ``dfs(``1``, ``1``)`   `    ``# Calculating LCA between U and V` `    ``LCA ``=` `lowestCommonAncestor(U, V)`   `    ``# Calculating LCA between U and R` `    ``LCA_1 ``=` `lowestCommonAncestor(U, R)`   `    ``# Calculating LCA between U and V` `    ``LCA_2 ``=` `lowestCommonAncestor(V, R)`   `    ``if` `LCA ``=``=` `R ``or` `(LCA_1 ``=``=` `LCA ``and` `LCA_2 ``=``=` `R) ``or` `(LCA_2 ``=``=` `LCA ``and` `LCA_1 ``=``=` `R):` `        ``return` `True` `    ``return` `False`   `# Create the graph` `preprocessing(n)` `Graph[``1``].append(``2``)` `Graph[``2``].append(``1``)` `Graph[``1``].append(``3``)` `Graph[``3``].append(``1``)` `Graph[``2``].append(``4``)` `Graph[``4``].append(``2``)` `Graph[``2``].append(``5``)` `Graph[``5``].append(``2``)` `Graph[``3``].append(``6``)` `Graph[``6``].append(``3``)`   `U, V, R ``=` `4``, ``6``, ``2` `if` `isPresent(U, V, R):` `  ``print``(``"Yes"``)` `else``:` `  ``print``(``"No"``)` `  `  `  ``# This code is contributed by suresh07.`

## C#

 `// C# implementation of the approach` `using` `System;` `using` `System.Collections.Generic;`   `class` `GfG ` `{`   `    ``// Table for storing 2^ith parent` `    ``private` `static` `int` `[,]table;`   `    ``// Variable to store the height of the tree` `    ``private` `static` `int` `height;`   `    ``// Graph` `    ``private` `static` `List > Graph;`   `    ``// Arrays to mark start and end time for a node` `    ``private` `static` `int` `[]timeIn;` `    ``private` `static` `int` `[]timeOut;`   `    ``// Timer` `    ``private` `static` `int` `time;`   `    ``// Private constructor for initializing` `    ``// the global variables` `    ``private` `GfG(``int` `n)` `    ``{`   `        ``// log(n) with base 2` `        ``height = (``int``)Math.Ceiling(Math.Log10(n) / Math.Log10(2));` `        ``table = ``new` `int``[n + 1, height + 1];`   `        ``// Fill the graph with empty lists` `        ``Graph = ``new` `List >();` `        ``for` `(``int` `i = 0; i <= n; i++)` `            ``Graph.Add(``new` `List<``int``>());` `        ``timeIn = ``new` `int``[n + 1];` `        ``timeOut = ``new` `int``[n + 1];` `        ``time = 0;` `    ``}`   `    ``// Filling with -1 as initial` `    ``private` `static` `void` `preprocessing(``int` `n)` `    ``{` `        ``for` `(``int` `i = 0; i < n + 1; i++) ` `        ``{` `            ``for``(``int` `j = 0; j < height + 1; j++)` `                ``table[i, j] = -1;` `        ``}` `    ``}`   `    ``// Dfs for pre-processing sparse table and` `    ``// calculating start and end time` `    ``private` `static` `void` `dfs(``int` `s, ``int` `p)` `    ``{` `        ``// Parent at 1 node distance is always` `        ``// it's direct parent` `        ``table[s, 0] = p;`   `        ``// Start time noted` `        ``timeIn[s] = ++time;`   `        ``// Filling sparse table recursively` `        ``for` `(``int` `i = 1; i <= height; i++)` `            ``table[s, i] = table[table[s, i - 1], i - 1];`   `        ``// Traversing children of source` `        ``foreach` `(``int` `child ``in` `Graph[s])` `        ``{` `            ``if` `(child == p)` `                ``continue``;` `            ``dfs(child, s);` `        ``}`   `        ``// End time noted` `        ``timeOut[s] = ++time;` `    ``}`   `    ``// Helper function to check lowest common Ancestor` `    ``private` `static` `bool` `check(``int` `u, ``int` `v)` `    ``{` `        ``return` `timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];` `    ``}`   `    ``// Function to return Lowest Common Ancestor of U and V` `    ``private` `static` `int` `lowestCommonAncestor(``int` `U, ``int` `V)` `    ``{` `        ``if` `(check(U, V))` `            ``return` `U;`   `        ``if` `(check(V, U))` `            ``return` `V;`   `        ``for` `(``int` `i = height; i >= 0; i--) ` `        ``{` `            ``if` `(!check(table[U, i], V))` `                ``U = table[U, i];` `        ``}`   `        ``return` `table[U, 0];` `    ``}`   `    ``// Function that return true if R` `    ``// exists on the path between U` `    ``// and V in the given tree` `    ``private` `static` `bool` `isPresent(``int` `U, ``int` `V, ``int` `R)` `    ``{`   `        ``// Dfs` `        ``dfs(1, 1);`   `        ``// Calculating LCA between U and V` `        ``int` `LCA = lowestCommonAncestor(U, V);`   `        ``// Calculating LCA between U and R` `        ``int` `LCA_1 = lowestCommonAncestor(U, R);`   `        ``// Calculating LCA between U and V` `        ``int` `LCA_2 = lowestCommonAncestor(V, R);`   `        ``if` `(LCA == R || (LCA_1 == LCA && LCA_2 == R)` `            ``|| (LCA_2 == LCA && LCA_1 == R)) ` `        ``{` `            ``return` `true``;` `        ``}` `        ``return` `false``;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `Main(String []args)` `    ``{` `        ``// Number of vertices` `        ``int` `n = 6;` `        ``GfG obj = ``new` `GfG(n);`   `        ``// Create the graph` `        ``preprocessing(n);` `        ``Graph[1].Add(2);` `        ``Graph[2].Add(1);` `        ``Graph[1].Add(3);` `        ``Graph[3].Add(1);` `        ``Graph[2].Add(4);` `        ``Graph[4].Add(2);` `        ``Graph[2].Add(5);` `        ``Graph[5].Add(2);` `        ``Graph[3].Add(6);` `        ``Graph[6].Add(3);`   `        ``int` `U = 4, V = 6, R = 2;` `        ``if` `(isPresent(U, V, R))` `            ``Console.Write(``"Yes"``);` `        ``else` `            ``Console.Write(``"No"``);` `    ``}` `}`   `// This code is contributed by PrinciRaj1992`

## Javascript

 ``

Output:

`Yes`

Time Complexity: O(NlogN) for pre-processing and logN for finding the lowest common ancestor.
Auxiliary Space: O(NlogN).

My Personal Notes arrow_drop_up
Related Articles