Find path between lowest and highest value in a Binary tree
Last Updated :
31 Oct, 2023
Given a binary tree consisting of N nodes. Find the path between the node having the lowest value to the node having the highest value. There is no restriction on the traversal, i.e. the tree can be traversed upward, bottom, left and right.
Examples:
Input: N = 8
2
/ \
1 6
/ \ \
4 21 26
/ \
5 7
{(2), (1, 6), (4, 21), (26), (5), (7)}
Output: 1 -> 2 -> 6 -> 26
Explanation: The minimum value in the tree is 1, while the maximum value is 26. So the path from the minimum value, i.e. 1 to the maximum value, i.e. 26 is 1 -> 2 -> 6 -> 26. Other than that, there is no other path from the node consisting of the minimum value to the node consisting of the maximum value.
Input: N = 5
10
/ \
5 20
/ \
17 25
{(10), (5, 20), (), (17, 25)}
Output: 5 -> 10 -> 20 -> 25
Explanation: The lowest node is 5 and the highest node is 25. The path between these two nodes is [5, 10, 20, 25].
Approach: This can be solved with the following idea:
- The first intuition that builds up in minds is to traverse the entire binary tree and find the node with the lowest and highest values.
- Then find the lowest common ancestor of the nodes with the lowest and highest values, then print the paths from the lowest node to the highest node using the parent pointers.
- We start at the highest value node and follow its parent pointers until we reach the lowest common ancestor. Then, we print the lowest common ancestor and follow the parent pointers of the lowest value node until we reach the next lowest common ancestor.
Below are the steps involved in the implementation of the code:
- The program below defines a TreeNode struct to represent a node in the binary tree.
- The findPath function takes the root node of the binary tree as input and finds the node with the lowest value and the node with the highest value by performing a breadth-first search of the tree.
- Then, the function traverses up from the lowest value node and the highest value node to find their common ancestor node.
- Finally, the function prints the path from the lowest value node to the common ancestor node and the path from the common ancestor node to the highest value node.
C++
// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
// A structure to represent the node
// of the tree
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode* parent;
TreeNode(int x)
: val(x), left(NULL), right(NULL), parent(NULL)
{
}
};
// Function to find path between the node
// having the lowest value to the node
// having the highest value.
void findPath(TreeNode* root)
{
TreeNode* minNode = root;
TreeNode* maxNode = root;
queue<TreeNode*> q;
q.push(root);
// Find the node with the lowest
// value and the node with
// the highest value
while (!q.empty()) {
TreeNode* node = q.front();
q.pop();
if (node->val < minNode->val)
minNode = node;
if (node->val > maxNode->val)
maxNode = node;
if (node->left) {
node->left->parent = node;
q.push(node->left);
}
if (node->right) {
node->right->parent = node;
q.push(node->right);
}
}
// Traverse up from the lowest value
// node until we reach the common
// ancestor node
while (minNode->parent != nullptr
&& minNode->parent->val > maxNode->val) {
minNode = minNode->parent;
}
// Traverse up from the highest value
// node until we reach the
// common ancestor node
while (maxNode->parent != nullptr
&& maxNode->parent->val < minNode->val) {
maxNode = maxNode->parent;
}
// Print the path from the lowest
// value node to the common
// ancestor node
cout << minNode->val << " ";
// Print the path from the common
// ancestor node to the
// highest value node
set<int> path;
while (maxNode != nullptr) {
path.insert(maxNode->val);
maxNode = maxNode->parent;
}
for (auto itr = path.begin(); itr != path.end();
itr++) {
cout << *itr << " ";
}
cout << endl;
}
// Driver code
int main()
{
TreeNode* root = new TreeNode(2);
root->left = new TreeNode(1);
root->right = new TreeNode(6);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(21);
root->right->right = new TreeNode(26);
root->left->left->left = new TreeNode(5);
root->left->right->right = new TreeNode(7);
root->parent = NULL;
// Function call
findPath(root);
return 0;
}
Java
// JAVA code for the above approach:
import java.util.*;
// A class to represent the node of the tree
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode parent;
TreeNode(int x)
{
val = x;
left = null;
right = null;
parent = null;
}
}
// Main class
public class Main {
// Function to find path between the node
// having the lowest value to the node
// having the highest value.
public static void findPath(TreeNode root)
{
TreeNode minNode = root;
TreeNode maxNode = root;
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
// Find the node with the lowest
// value and the node with
// the highest value
while (!q.isEmpty()) {
TreeNode node = q.poll();
if (node.val < minNode.val)
minNode = node;
if (node.val > maxNode.val)
maxNode = node;
if (node.left != null) {
node.left.parent = node;
q.add(node.left);
}
if (node.right != null) {
node.right.parent = node;
q.add(node.right);
}
}
// Traverse up from the lowest value
// node until we reach the common
// ancestor node
while (minNode.parent != null
&& minNode.parent.val > maxNode.val) {
minNode = minNode.parent;
}
// Traverse up from the highest value
// node until we reach the
// common ancestor node
while (maxNode.parent != null
&& maxNode.parent.val < minNode.val) {
maxNode = maxNode.parent;
}
// Print the path from the lowest
// value node to the common
// ancestor node
System.out.print(minNode.val + " ");
// Print the path from the common
// ancestor node to the
// highest value node
Set<Integer> path = new TreeSet<>();
while (maxNode != null) {
path.add(maxNode.val);
maxNode = maxNode.parent;
}
for (int val : path) {
System.out.print(val + " ");
}
System.out.println();
}
// Driver code
public static void main(String[] args)
{
TreeNode root = new TreeNode(2);
root.left = new TreeNode(1);
root.right = new TreeNode(6);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(21);
root.right.right = new TreeNode(26);
root.left.left.left = new TreeNode(5);
root.left.right.right = new TreeNode(7);
root.parent = null;
// Function call
findPath(root);
}
}
// This code is contributed by rambabuguphka
Python3
from queue import Queue
# A class to represent the node of the tree
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
self.parent = None
# Function to find the path between the node
# having the lowest value to the node
# having the highest value.
def find_path(root):
min_node = root
max_node = root
q = Queue()
q.put(root)
# Find the node with the lowest
# value and the node with the
# highest value
while not q.empty():
node = q.get()
if node.val < min_node.val:
min_node = node
if node.val > max_node.val:
max_node = node
if node.left:
node.left.parent = node
q.put(node.left)
if node.right:
node.right.parent = node
q.put(node.right)
# Traverse up from the lowest value
# node until we reach the common
# ancestor node
while min_node.parent is not None and min_node.parent.val > max_node.val:
min_node = min_node.parent
# Traverse up from the highest value
# node until we reach the
# common ancestor node
while max_node.parent is not None and max_node.parent.val < min_node.val:
max_node = max_node.parent
# Print the path from the lowest
# value node to the common
# ancestor node
print(min_node.val, end=" ")
# Print the path from the common
# ancestor node to the
# highest value node
path = set()
while max_node is not None:
path.add(max_node.val)
max_node = max_node.parent
for val in sorted(path):
print(val, end=" ")
print()
# Driver code
if __name__ == "__main__":
# Create the binary tree
root = TreeNode(2)
root.left = TreeNode(1)
root.right = TreeNode(6)
root.left.left = TreeNode(4)
root.left.right = TreeNode(21)
root.right.right = TreeNode(26)
root.left.left.left = TreeNode(5)
root.left.right.right = TreeNode(7)
root.parent = None
# Function call to find and print the path
find_path(root)
C#
// C# code for the above approach:
using System;
using System.Collections.Generic;
// A class to represent the node of the tree
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode parent;
public TreeNode(int x)
{
val = x;
left = null;
right = null;
parent = null;
}
}
// Main class
public class GFG
{
// Function to find path between the node
// having the lowest value to the node
// having the highest value.
public static void FindPath(TreeNode root)
{
TreeNode minNode = root;
TreeNode maxNode = root;
Queue<TreeNode> q = new Queue<TreeNode>();
q.Enqueue(root);
// Find the node with the lowest
// value and the node with
// the highest value
while (q.Count > 0)
{
TreeNode node = q.Dequeue();
if (node.val < minNode.val)
minNode = node;
if (node.val > maxNode.val)
maxNode = node;
if (node.left != null)
{
node.left.parent = node;
q.Enqueue(node.left);
}
if (node.right != null)
{
node.right.parent = node;
q.Enqueue(node.right);
}
}
// Traverse up from the lowest value
// node until we reach the common
// ancestor node
while (minNode.parent != null
&& minNode.parent.val > maxNode.val)
{
minNode = minNode.parent;
}
// Traverse up from the highest value
// node until we reach the
// common ancestor node
while (maxNode.parent != null
&& maxNode.parent.val < minNode.val)
{
maxNode = maxNode.parent;
}
// Print the path from the lowest
// value node to the common
// ancestor node
Console.Write(minNode.val + " ");
// Print the path from the common
// ancestor node to the
// highest value node
SortedSet<int> path = new SortedSet<int>();
while (maxNode != null)
{
path.Add(maxNode.val);
maxNode = maxNode.parent;
}
foreach (int val in path)
{
Console.Write(val + " ");
}
Console.WriteLine();
}
// Driver code
public static void Main(string[] args)
{
TreeNode root = new TreeNode(2);
root.left = new TreeNode(1);
root.right = new TreeNode(6);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(21);
root.right.right = new TreeNode(26);
root.left.left.left = new TreeNode(5);
root.left.right.right = new TreeNode(7);
root.parent = null;
// Function call
FindPath(root);
}
}
// This code is contributed by Sakshi
JavaScript
<script>
// Javascript code for the above approach:
// A class to represent the node
// of the tree
class TreeNode {
constructor(val) {
this.val = val;
this.left = null;
this.right = null;
this.parent = null;
}
}
// Function to find path between the node
// having the lowest value to the node
// having the highest value.
function findPath(root) {
let minNode = root;
let maxNode = root;
const queue = [];
queue.push(root);
// Find the node with the lowest
// value and the node with
// the highest value
while (queue.length !== 0) {
const node = queue.shift();
if (node.val < minNode.val)
minNode = node;
if (node.val > maxNode.val)
maxNode = node;
if (node.left) {
node.left.parent = node;
queue.push(node.left);
}
if (node.right) {
node.right.parent = node;
queue.push(node.right);
}
}
// Traverse up from the lowest value
// node until we reach the common
// ancestor node
while (minNode.parent !== null
&& minNode.parent.val > maxNode.val) {
minNode = minNode.parent;
}
// Traverse up from the highest value
// node until we reach the
// common ancestor node
while (maxNode.parent !== null
&& maxNode.parent.val < minNode.val) {
maxNode = maxNode.parent;
}
// Print the path from the lowest
// value node to the
// highest value node
let path = [];
while (maxNode !== null) {
path.push(maxNode.val);
maxNode = maxNode.parent;
}
document.write(minNode.val + " " + path.reverse().join(" "));
}
// Driver code
function main() {
const root = new TreeNode(2);
root.left = new TreeNode(1);
root.right = new TreeNode(6);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(21);
root.right.right = new TreeNode(26);
root.left.left.left = new TreeNode(5);
root.left.right.right = new TreeNode(7);
root.parent = null;
// Function call
findPath(root);
}
main();
// This code is contributed by Pushpesh Raj
</script>
Time Complexity: O(N)
Auxiliary Space: O(h)
Similar Reads
Relationship between number of nodes and height of binary tree Binary Tree is a hierarchical data structure in which each node has at most two children, referred to as the left child and the right child. It is commonly used in computer science for efficient storage and retrieval of data, with various operations such as insertion, deletion, and traversal.Prerequ
2 min read
Count nodes having highest value in the path from root to itself in a Binary Tree Given a Binary Tree, the task is to count the number of nodes in the Binary Tree, which are the highest valued node in the path from the root up to that node. Examples: Input: Below is the given Tree: 3 / \ 2 5 / \ 4 6Output: 4Explanation:Root node satisfies the required condition.Node 5 is the high
8 min read
Maximum difference between node and its ancestor in Binary Tree Given a Binary tree, The task is to find the maximum value by subtracting the value of node B from the value of node A, where A and B are two nodes of the binary tree and A is an ancestor of B. Examples: Input: Output: 7Explanation: We can have various ancestor-node difference, some of which are giv
10 min read
Find the maximum node at a given level in a binary tree Given a Binary Tree and a Level. The task is to find the node with the maximum value at that given level. The idea is to traverse the tree along depth recursively and return the nodes once the required level is reached and then return the maximum of left and right subtrees for each subsequent call.
13 min read
Find the largest Perfect Subtree in a given Binary Tree Given a Binary Tree, the task is to find the size of largest Perfect sub-tree in the given Binary Tree. Perfect Binary Tree - A Binary tree is Perfect Binary Tree in which all internal nodes have two children and all leaves are at the same level. Examples: Input: 1 / \ 2 3 / \ / 4 5 6 Output: Size :
12 min read