Given a full binary tree where each node value is the same as the minimum value between its children, the task is to find the second minimum unique value of the tree.
Examples:
Input: tree:
![]()
Example of the problem statement
Output: 5
Explanation: All the unique values present in the tree are 2, 5 and 7.
The second smallest is 5.Input: tree:
![]()
Another example of a problem statement
Output: -1
Explanation: All the numbers present in the tree are same.Â
There is no other value except 2, so second smallest is not possible.
Naive Approach: The basic approach to solve the problem is based on the idea:
Store all the unique values in an array and sort the array. Then find the second minimum from the array.
Follow the below step to understand the approach more clearly:
- Traverse the tree and store all the values in an array.
- Sort the array.
- Iterate over the array and find the first array element which is not equal to the minimum element of the array (i.e. the one present at index 0). If no such element is present then return -1.
Below is the implementation of the above approach.
C++
// C++ code to implement the above approach Â
#include <bits/stdc++.h> using namespace std; Â
// Structure of a tree node struct Node { Â Â Â Â int data; Â Â Â Â struct Node* left; Â Â Â Â struct Node* right; Â Â Â Â Node( int val) Â Â Â Â { Â Â Â Â Â Â Â Â data = val; Â Â Â Â Â Â Â Â left = NULL; Â Â Â Â Â Â Â Â right = NULL; Â Â Â Â } }; Â
// Initialize a vector vector< int > ans; Â
// Traversing the tree by using inorder // traversal void inorderTraversal(Node* root) { Â Â Â Â if (root != NULL) { Â Â Â Â Â Â Â Â inorderTraversal(root->left); Â Â Â Â Â Â Â Â ans.push_back(root->data); Â Â Â Â Â Â Â Â inorderTraversal(root->right); Â Â Â Â } } Â
// Function to find the second minimum element int findSecondMinimumValue(Node* root) { Â Â Â Â inorderTraversal(root); Â
    // Sorting the array element     sort(ans.begin(), ans.end()); Â
    // Traversing and array and checking     // the second minimum element     for ( int i = 0; i < ans.size() - 1; i++)         if (ans[i] != ans[i + 1])             return ans[i + 1];     return -1; } Â
// Driver code int main() {     // Creating the tree     // 2     //       / \     // 2  5     //         / \     // 5  7     struct Node* root = new Node(2);     root->left = new Node(2);     root->right = new Node(5);     root->right->left = new Node(5);     root->right->right = new Node(7); Â
    // Function call     int SecondMinimumValue         = findSecondMinimumValue(root);     cout << SecondMinimumValue << endl;     return 0; } |
Java
// JAVA code to implement the above approach import java.util.*; Â
class GFG { Â
  // Structure of a tree node   public static class Node {     int data;     Node left;     Node right;     Node( int val) { this .data = val; }   } Â
  // Initialize a vector   public static ArrayList<Integer> ans     = new ArrayList<Integer>(); Â
  // Traversing the tree by using inorder   // traversal   public static void inorderTraversal(Node root)   {     if (root != null ) {       inorderTraversal(root.left);       ans.add(root.data);       inorderTraversal(root.right);     }   } Â
  // Function to find the second minimum element   public static int findSecondMinimumValue(Node root)   {     inorderTraversal(root); Â
    // Sorting the array element     Collections.sort(ans); Â
    // Traversing and array and checking     // the second minimum element     for ( int i = 0 ; i < ans.size() - 1 ; i++)       if (ans.get(i) != ans.get(i + 1 ))         return ans.get(i + 1 );     return - 1 ;   } Â
  // Driver code   public static void main(String[] args)   {     // Creating the tree     // 2     //       / \     // 2  5     //         / \     // 5  7     Node root = new Node( 2 );     root.left = new Node( 2 );     root.right = new Node( 5 );     root.right.left = new Node( 5 );     root.right.right = new Node( 7 ); Â
    // Function call     int SecondMinimumValue       = findSecondMinimumValue(root);     System.out.println(SecondMinimumValue);   } } Â
// This code is contributed by Taranpreet |
Python3
# Python3 code for the above approach Â
# class to create a tree node class Node:     def __init__( self , d):         self .data = d         self .left = None         self .right = None              # Initialize a list ans = [] Â
# Traversing the tree by using inorder # traversal def inorderTraversal(root) : Â Â Â Â if (root ! = None ) : Â Â Â Â Â Â Â Â inorderTraversal(root.left) Â Â Â Â Â Â Â Â ans.append(root.data) Â Â Â Â Â Â Â Â inorderTraversal(root.right) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
    # Function to find the second minimum element def findSecondMinimumValue(root) :     inorderTraversal(root) Â
    # Sorting the array element     ans.sort() Â
    # Traversing and array and checking     # the second minimum element     for i in range ( 0 , len (ans) - 1 ) :         if (ans[i] ! = ans[i + 1 ]) :             return ans[i + 1 ]     return - 1 Â
# Driver Code if __name__ = = '__main__' : Â Â Â Â Â Â Â Â Â Â Â Â Â # Driver code Â
    # Creating the tree     #  2     # / \     # 2  5     #   / \     #  5  7     root = Node( 2 )     root.left = Node( 2 )     root.right = Node( 5 )     root.right.left = Node( 5 )     root.right.right = Node( 7 ) Â
    # Function call     SecondMinimumValue = findSecondMinimumValue(root)     print (SecondMinimumValue) Â
    # This code is contributed by jana_sayantan. |
Javascript
<script> Â Â Â Â Â Â Â // JavaScript code for the above approach Â
       // Structure of a tree node        class Node { Â
           constructor(val) {                this .data = val;                this .left = null ;                this .right = null ;            }        }; Â
       // Initialize a vector        let ans = []; Â
       // Traversing the tree by using inorder        // traversal        function inorderTraversal(root) {            if (root != null ) {                inorderTraversal(root.left);                ans.push(root.data);                inorderTraversal(root.right);            }        } Â
       // Function to find the second minimum element        function findSecondMinimumValue(root) {            inorderTraversal(root); Â
           // Sorting the array element            ans.sort(); Â
           // Traversing and array and checking            // the second minimum element            for (let i = 0; i < ans.length - 1; i++)                if (ans[i] != ans[i + 1])                    return ans[i + 1];            return -1;        } Â
       // Driver code Â
       // Creating the tree        // 2        //       / \        // 2  5        //         / \        // 5  7        let root = new Node(2);        root.left = new Node(2);        root.right = new Node(5);        root.right.left = new Node(5);        root.right.right = new Node(7); Â
       // Function call        let SecondMinimumValue            = findSecondMinimumValue(root);        document.write(SecondMinimumValue + '<br>' ); Â
   // This code is contributed by Potta Lokesh    </script> |
C#
// C# code to implement the above approach using System; using System.Collections.Generic; Â
public class GFG { Â
  // Structure of a tree node   public class Node {     public int data;     public Node left;     public Node right;     public Node( int val) { this .data = val; }   } Â
  // Initialize a vector   public static List< int > ans     = new List< int >(); Â
  // Traversing the tree by using inorder   // traversal   public static void inorderTraversal(Node root)   {     if (root != null ) {       inorderTraversal(root.left);       ans.Add(root.data);       inorderTraversal(root.right);     }   } Â
  // Function to find the second minimum element   public static int findSecondMinimumValue(Node root)   {     inorderTraversal(root); Â
    // Sorting the array element     ans.Sort(); Â
    // Traversing and array and checking     // the second minimum element     for ( int i = 0; i < ans.Count - 1; i++)       if (ans[i] != ans[i + 1])         return ans[i + 1];     return -1;   } Â
  // Driver code   public static void Main(String[] args)   {     // Creating the tree     // 2     //       / \     // 2  5     //         / \     // 5  7     Node root = new Node(2);     root.left = new Node(2);     root.right = new Node(5);     root.right.left = new Node(5);     root.right.right = new Node(7); Â
    // Function call     int SecondMinimumValue       = findSecondMinimumValue(root);     Console.WriteLine(SecondMinimumValue);   } } Â
Â
// This code contributed by shikhasingrajput |
5
Time Complexity: O(N * logN)
Auxiliary Space: O(N)
Efficient Approach: The problem can be solved efficiently by using the below observation:
The root node of the tree contains the minimum among all the nodes.Â
If the value of all the nodes with minimum value is replaced by some other arbitrary numbers out of the range of tree values and the tree property is maintained then the root node will have the current minimum value which is actually the second minimum of the given tree.
The above observation can be implemented using recursion. Follow the approach mentioned below to implement the idea of the above observation:
- Use a recursive function to traverse the tree and implement the observation.
- In each recursion for any node:
- Find which of its children has the same value as the root and call the next recursion for that child.
- If the value of the current node is the same as the root and does not have any children, or both children have same value replace its value with -1.
- If the current node has children, replace it with the minimum of its children while returning from the recursive function. (This will replace the value with the second minimum as the minimum is replaced with -1 and -1 is not being considered for checking the minimum).
- In this way, while the traversal is complete, the tree root holds the current minimum of the tree which is actually the second minimum of the original tree.Â
- Return the value of the root.
Below is the code of the above approach:Â
C++
// C++ program for above approach Â
#include <bits/stdc++.h> using namespace std; Â
// Structure of a tree node struct Node { Â Â Â Â int data; Â Â Â Â struct Node* left; Â Â Â Â struct Node* right; Â Â Â Â Node( int val) Â Â Â Â { Â Â Â Â Â Â Â Â data = val; Â Â Â Â Â Â Â Â left = NULL; Â Â Â Â Â Â Â Â right = NULL; Â Â Â Â } }; Â
// Function to find the minimum value int findSecondMinimumValue(Node* root) {     // When the root is null     if (!root)         return -1; Â
    // Base Condition     // When we reach the Leaf node then     // in that case we have to return -1     // as per the algorithm stated in     // the above statement     if (!root->left && !root->right)         return -1; Â
    // Storing the Node value of the left     // child of the Node     auto left = root->left->data; Â
    // Storing the Node value of the right     // child of the Node     auto right = root->right->data; Â
    // Call the function recursively to the     // left sub-part of the tree if the value     // of the node value matches with its left     // child node value     if (root->data == root->left->data)         left             = findSecondMinimumValue(root->left); Â
    // Call the function recursively to the     // right sub-part of the tree if the     // value of the node value matches with     // its right child node value     if (root->data == root->right->data)         right             = findSecondMinimumValue(root->right); Â
    // In case if both the left and right     // child value is not equal to -1 then     // in that case return the minimum of     // them to its parent     if (left != -1 && right != -1)         return min(left, right); Â
    // In case if the left child's value is     // not equal to -1 BUT its right child's     // value is equal to -1 then in that case     // send the left child value to its     // parent node.     else if (left != -1)         return left; Â
    // In case if the right child's value is     // not equal to -1 BUT its left child's     // value is equal to -1 then in that case     // send the right child value to its     // parent node.     else         return right; } Â
// Driver code int main() {     // Creating the root node     /*        2               / \              2  5                 / \                5  7 */     struct Node* root = new Node(2);     root->left = new Node(2);     root->right = new Node(5);     root->right->left = new Node(5);     root->right->right = new Node(7); Â
    int SecondMinimumValue         = findSecondMinimumValue(root);     cout << SecondMinimumValue << endl;     return 0; } |
C
// C program for above approach Â
#include <stdio.h> #include <stdlib.h> Â
// Structure of a tree node typedef struct Node { Â Â Â Â int data; Â Â Â Â struct Node* left; Â Â Â Â struct Node* right; } Node; Â
Node* newNode( int data) { Â Â Â Â Node* new_node = (Node*) malloc ( sizeof (Node)); Â Â Â Â new_node->data = data; Â Â Â Â new_node->left = new_node->right = NULL; Â Â Â Â return new_node; } Â
// Find minimum between two numbers. int min( int num1, int num2) { Â Â return (num1 > num2) ? num2 : num1; } Â
// Function to find the minimum value int findSecondMinimumValue(Node* root) {     // When the root is null     if (!root)         return -1; Â
    // Base Condition     // When we reach the Leaf node then     // in that case we have to return -1     // as per the algorithm stated in     // the above statement     if (!root->left && !root->right)         return -1; Â
    // Storing the Node value of the left     // child of the Node     int left = root->left->data; Â
    // Storing the Node value of the right     // child of the Node     int right = root->right->data; Â
    // Call the function recursively to the     // left sub-part of the tree if the value     // of the node value matches with its left     // child node value     if (root->data == root->left->data)         left = findSecondMinimumValue(root->left); Â
    // Call the function recursively to the     // right sub-part of the tree if the     // value of the node value matches with     // its right child node value     if (root->data == root->right->data)         right = findSecondMinimumValue(root->right); Â
    // In case if both the left and right     // child value is not equal to -1 then     // in that case return the minimum of     // them to the its parent     if (left != -1 && right != -1)         return min(left, right); Â
    // In case if the left child's value is     // not equal to -1 BUT its right child's     // value is equal to -1 then in that case     // send the left child value to its     // parent node.     else if (left != -1)         return left; Â
    // In case if the right child's value is     // not equal to -1 BUT its left child's     // value is equal to -1 then in that case     // send the right child value to its     // parent node.     else         return right; } Â
// Driver code int main() {     // Creating the root node     /*        2               / \              2  5                 / \                5  7 */     Node* root = newNode(2);     root->left = newNode(2);     root->right = newNode(5);     root->right->left = newNode(5);     root->right->right = newNode(7); Â
    int SecondMinimumValue = findSecondMinimumValue(root);     printf ( "%d\n" , SecondMinimumValue);     return 0; } Â
// This code is contributed by Sania Kumari Gupta |
Java
/*package whatever //do not write package name here */ import java.io.*; import java.util.*; Â
class GFG { Â
  static class Node {     int data;     Node left;     Node right;     Node( int val)     {       data = val;       left = null ;       right = null ;     }   } Â
  // Function to find the minimum value   static int findSecondMinimumValue(Node root)   {     // When the root is null     if (root== null )       return - 1 ; Â
    // Base Condition     // When we reach the Leaf node then     // in that case we have to return -1     // as per the algorithm stated in     // the above statement     if (root.left== null && root.right== null )       return - 1 ; Â
    // Storing the Node value of the left     // child of the Node     int left = root.left.data; Â
    // Storing the Node value of the right     // child of the Node     int right = root.right.data; Â
    // Call the function recursively to the     // left sub-part of the tree if the value     // of the node value matches with its left     // child node value     if (root.data == root.left.data)       left = findSecondMinimumValue(root.left); Â
    // Call the function recursively to the     // right sub-part of the tree if the     // value of the node value matches with     // its right child node value     if (root.data == root.right.data)       right = findSecondMinimumValue(root.right); Â
    // In case if both the left and right     // child value is not equal to -1 then     // in that case return the minimum of     // them to the its parent     if (left != - 1 && right != - 1 )       return Math.min(left, right); Â
    // In case if the left child's value is     // not equal to -1 BUT its right child's     // value is equal to -1 then in that case     // send the left child value to its     // parent node.     else if (left != - 1 )       return left; Â
    // In case if the right child's value is     // not equal to -1 BUT its left child's     // value is equal to -1 then in that case     // send the right child value to its     // parent node.     else       return right;   } Â
Â
  public static void main (String[] args) { Â
    // Creating the root node     /*        2               / \              2  5                 / \                5  7 */     Node root = new Node( 2 );     root.left = new Node( 2 );     root.right = new Node( 5 );     root.right.left = new Node( 5 );     root.right.right = new Node( 7 ); Â
    int SecondMinimumValue = findSecondMinimumValue(root); Â
    System.out.println(SecondMinimumValue);   } } Â
// This code is contributed by aadityaburujwale. |
Python3
# Python program to implement above approach Â
# Structure of a tree node class Node:     def __init__( self ,val):         self .data = val         self .left = None         self .right = None      Â
# Function to find the minimum value def findSecondMinimumValue(root):     # When the root is None     if (root = = None ):         return - 1 Â
    # Base Condition     # When we reach the Leaf node then     # in that case we have to return -1     # as per the algorithm stated in     # the above statement     if (root.left = = None and root.right = = None ):         return - 1 Â
    # Storing the Node value of the left     # child of the Node     left = root.left.data Â
    # Storing the Node value of the right     # child of the Node     right = root.right.data Â
    # Call the function recursively to the     # left sub-part of the tree if the value     # of the node value matches with its left     # child node value     if (root.data = = root.left.data):         left = findSecondMinimumValue(root.left) Â
    # Call the function recursively to the     # right sub-part of the tree if the     # value of the node value matches with     # its right child node value     if (root.data = = root.right.data):         right = findSecondMinimumValue(root.right) Â
    # In case if both the left and right     # child value is not equal to -1 then     # in that case return the minimum of     # them to the its parent     if (left ! = - 1 and right ! = - 1 ):         return min (left, right) Â
    # In case if the left child's value is     # not equal to -1 BUT its right child's     # value is equal to -1 then in that case     # send the left child value to its     # parent node.     elif (left ! = - 1 ):         return left Â
    # In case if the right child's value is     # not equal to -1 BUT its left child's     # value is equal to -1 then in that case     # send the right child value to its     # parent node.     else :         return right Â
# Driver code Â
root = Node( 2 ) root.left = Node( 2 ) root.right = Node( 5 ) root.right.left = Node( 5 ) root.right.right = Node( 7 ) Â Â Â Â Â Â Â Â Â SecondMinimumValue = findSecondMinimumValue(root) print (SecondMinimumValue) Â
# This code is contributed by shinjanpatra |
C#
// C# program for above approach using System; Â
public class GFG { Â
  class Node {     public int data;     public Node left;     public Node right;     public Node( int val)     {       data = val;       left = null ;       right = null ;     }   } Â
  // Function to find the minimum value   static int findSecondMinimumValue(Node root)   {     // When the root is null     if (root == null )       return -1; Â
    // Base Condition     // When we reach the Leaf node then     // in that case we have to return -1     // as per the algorithm stated in     // the above statement     if (root.left == null && root.right == null )       return -1; Â
    // Storing the Node value of the left     // child of the Node     int left = root.left.data; Â
    // Storing the Node value of the right     // child of the Node     int right = root.right.data; Â
    // Call the function recursively to the     // left sub-part of the tree if the value     // of the node value matches with its left     // child node value     if (root.data == root.left.data)       left = findSecondMinimumValue(root.left); Â
    // Call the function recursively to the     // right sub-part of the tree if the     // value of the node value matches with     // its right child node value     if (root.data == root.right.data)       right = findSecondMinimumValue(root.right); Â
    // In case if both the left and right     // child value is not equal to -1 then     // in that case return the minimum of     // them to the its parent     if (left != -1 && right != -1)       return Math.Min(left, right); Â
    // In case if the left child's value is     // not equal to -1 BUT its right child's     // value is equal to -1 then in that case     // send the left child value to its     // parent node.     else if (left != -1)       return left; Â
    // In case if the right child's value is     // not equal to -1 BUT its left child's     // value is equal to -1 then in that case     // send the right child value to its     // parent node.     else       return right;   } Â
  static public void Main()   { Â
    // Code     // Creating the root node     /*        2                   / \                  2  5                     / \                    5  7 */     Node root = new Node(2);     root.left = new Node(2);     root.right = new Node(5);     root.right.left = new Node(5);     root.right.right = new Node(7); Â
    int SecondMinimumValue       = findSecondMinimumValue(root); Â
    Console.WriteLine(SecondMinimumValue);   } } Â
// This code is contributed by lokeshmvs21. |
Javascript
<script> Â
// JavaScript program to implement above approach Â
// Structure of a tree node class Node {Â Â Â Â Â Â Â constructor(val) Â Â Â Â { Â Â Â Â Â Â Â Â this .data = val; Â Â Â Â Â Â Â Â this .left = null ; Â Â Â Â Â Â Â Â this .right = null ; Â Â Â Â } }; Â
// Function to find the minimum value function findSecondMinimumValue(root) {     // When the root is null     if (!root)         return -1; Â
    // Base Condition     // When we reach the Leaf node then     // in that case we have to return -1     // as per the algorithm stated in     // the above statement     if (!root.left && !root.right)         return -1; Â
    // Storing the Node value of the left     // child of the Node     let left = root.left.data; Â
    // Storing the Node value of the right     // child of the Node     let right = root.right.data; Â
    // Call the function recursively to the     // left sub-part of the tree if the value     // of the node value matches with its left     // child node value     if (root.data == root.left.data)         left = findSecondMinimumValue(root.left); Â
    // Call the function recursively to the     // right sub-part of the tree if the     // value of the node value matches with     // its right child node value     if (root.data == root.right.data)         right = findSecondMinimumValue(root.right); Â
    // In case if both the left and right     // child value is not equal to -1 then     // in that case return the minimum of     // them to the its parent     if (left != -1 && right != -1)         return Math.min(left, right); Â
    // In case if the left child's value is     // not equal to -1 BUT its right child's     // value is equal to -1 then in that case     // send the left child value to its     // parent node.     else if (left != -1)         return left; Â
    // In case if the right child's value is     // not equal to -1 BUT its left child's     // value is equal to -1 then in that case     // send the right child value to its     // parent node.     else         return right; } Â
// Driver code Â
let root = new Node(2); root.left = new Node(2); root.right = new Node(5); root.right.left = new Node(5); root.right.right = new Node(7); Â Â Â Â Â Â Â Â Â let SecondMinimumValue = findSecondMinimumValue(root); document.write(SecondMinimumValue, "</br>" ); Â
// This code is contributed by shinjanpatra Â
</script> |
5
Time Complexity: O(H) where H is the height of the tree
Auxiliary Space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!