Second unique smallest value of given Binary Tree whose each node is minimum of its children
Last Updated :
09 Nov, 2022
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++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* left;
struct Node* right;
Node( int val)
{
data = val;
left = NULL;
right = NULL;
}
};
vector< int > ans;
void inorderTraversal(Node* root)
{
if (root != NULL) {
inorderTraversal(root->left);
ans.push_back(root->data);
inorderTraversal(root->right);
}
}
int findSecondMinimumValue(Node* root)
{
inorderTraversal(root);
sort(ans.begin(), ans.end());
for ( int i = 0; i < ans.size() - 1; i++)
if (ans[i] != ans[i + 1])
return ans[i + 1];
return -1;
}
int main()
{
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;
}
|
Java
import java.util.*;
class GFG
{
public static class Node {
int data;
Node left;
Node right;
Node( int val) { this .data = val; }
}
public static ArrayList<Integer> ans
= new ArrayList<Integer>();
public static void inorderTraversal(Node root)
{
if (root != null ) {
inorderTraversal(root.left);
ans.add(root.data);
inorderTraversal(root.right);
}
}
public static int findSecondMinimumValue(Node root)
{
inorderTraversal(root);
Collections.sort(ans);
for ( int i = 0 ; i < ans.size() - 1 ; i++)
if (ans.get(i) != ans.get(i + 1 ))
return ans.get(i + 1 );
return - 1 ;
}
public static void main(String[] args)
{
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);
}
}
|
Python3
class Node:
def __init__( self , d):
self .data = d
self .left = None
self .right = None
ans = []
def inorderTraversal(root) :
if (root ! = None ) :
inorderTraversal(root.left)
ans.append(root.data)
inorderTraversal(root.right)
def findSecondMinimumValue(root) :
inorderTraversal(root)
ans.sort()
for i in range ( 0 , len (ans) - 1 ) :
if (ans[i] ! = ans[i + 1 ]) :
return ans[i + 1 ]
return - 1
if __name__ = = '__main__' :
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)
|
Javascript
<script>
class Node {
constructor(val) {
this .data = val;
this .left = null ;
this .right = null ;
}
};
let ans = [];
function inorderTraversal(root) {
if (root != null ) {
inorderTraversal(root.left);
ans.push(root.data);
inorderTraversal(root.right);
}
}
function findSecondMinimumValue(root) {
inorderTraversal(root);
ans.sort();
for (let i = 0; i < ans.length - 1; i++)
if (ans[i] != ans[i + 1])
return ans[i + 1];
return -1;
}
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>' );
</script>
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
public class Node {
public int data;
public Node left;
public Node right;
public Node( int val) { this .data = val; }
}
public static List< int > ans
= new List< int >();
public static void inorderTraversal(Node root)
{
if (root != null ) {
inorderTraversal(root.left);
ans.Add(root.data);
inorderTraversal(root.right);
}
}
public static int findSecondMinimumValue(Node root)
{
inorderTraversal(root);
ans.Sort();
for ( int i = 0; i < ans.Count - 1; i++)
if (ans[i] != ans[i + 1])
return ans[i + 1];
return -1;
}
public static void Main(String[] args)
{
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);
}
}
|
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++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* left;
struct Node* right;
Node( int val)
{
data = val;
left = NULL;
right = NULL;
}
};
int findSecondMinimumValue(Node* root)
{
if (!root)
return -1;
if (!root->left && !root->right)
return -1;
auto left = root->left->data;
auto right = root->right->data;
if (root->data == root->left->data)
left
= findSecondMinimumValue(root->left);
if (root->data == root->right->data)
right
= findSecondMinimumValue(root->right);
if (left != -1 && right != -1)
return min(left, right);
else if (left != -1)
return left;
else
return right;
}
int main()
{
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
#include <stdio.h>
#include <stdlib.h>
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;
}
int min( int num1, int num2)
{
return (num1 > num2) ? num2 : num1;
}
int findSecondMinimumValue(Node* root)
{
if (!root)
return -1;
if (!root->left && !root->right)
return -1;
int left = root->left->data;
int right = root->right->data;
if (root->data == root->left->data)
left = findSecondMinimumValue(root->left);
if (root->data == root->right->data)
right = findSecondMinimumValue(root->right);
if (left != -1 && right != -1)
return min(left, right);
else if (left != -1)
return left;
else
return right;
}
int main()
{
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;
}
|
Java
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 ;
}
}
static int findSecondMinimumValue(Node root)
{
if (root== null )
return - 1 ;
if (root.left== null && root.right== null )
return - 1 ;
int left = root.left.data;
int right = root.right.data;
if (root.data == root.left.data)
left = findSecondMinimumValue(root.left);
if (root.data == root.right.data)
right = findSecondMinimumValue(root.right);
if (left != - 1 && right != - 1 )
return Math.min(left, right);
else if (left != - 1 )
return left;
else
return right;
}
public static void main (String[] args) {
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);
}
}
|
Python3
class Node:
def __init__( self ,val):
self .data = val
self .left = None
self .right = None
def findSecondMinimumValue(root):
if (root = = None ):
return - 1
if (root.left = = None and root.right = = None ):
return - 1
left = root.left.data
right = root.right.data
if (root.data = = root.left.data):
left = findSecondMinimumValue(root.left)
if (root.data = = root.right.data):
right = findSecondMinimumValue(root.right)
if (left ! = - 1 and right ! = - 1 ):
return min (left, right)
elif (left ! = - 1 ):
return left
else :
return right
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)
|
C#
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 ;
}
}
static int findSecondMinimumValue(Node root)
{
if (root == null )
return -1;
if (root.left == null && root.right == null )
return -1;
int left = root.left.data;
int right = root.right.data;
if (root.data == root.left.data)
left = findSecondMinimumValue(root.left);
if (root.data == root.right.data)
right = findSecondMinimumValue(root.right);
if (left != -1 && right != -1)
return Math.Min(left, right);
else if (left != -1)
return left;
else
return right;
}
static public void Main()
{
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);
}
}
|
Javascript
<script>
class Node {
constructor(val)
{
this .data = val;
this .left = null ;
this .right = null ;
}
};
function findSecondMinimumValue(root)
{
if (!root)
return -1;
if (!root.left && !root.right)
return -1;
let left = root.left.data;
let right = root.right.data;
if (root.data == root.left.data)
left = findSecondMinimumValue(root.left);
if (root.data == root.right.data)
right = findSecondMinimumValue(root.right);
if (left != -1 && right != -1)
return Math.min(left, right);
else if (left != -1)
return left;
else
return right;
}
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>" );
</script>
|
Time Complexity: O(H) where H is the height of the tree
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...