Let represent the ordered pair of the second maximum and the maximum element of an array respectively. We need to find all such unique pairs overall contiguous sub-arrays of a given array.
Examples:
Input: Arr = [ 1, 2, 3, 4, 5 ]
Output: (1, 2) (2, 3) (3, 4) (4, 5)Input: Arr = [ 1, 1, 2 ]
Output: (1, 1) (1, 2)Input: Arr = [ 1, 2, 6, 4, 5 ]
Output: (1, 2) (2, 6) (4, 5) (4, 6) (5, 6)
Brute Force Approach:
- A simple way to solve this problem would be to scan each sub-array and find the maximum and second maximum element in that sub-array
- This can be done in time
- Then we can insert each pair in a set to ensure duplicates are removed, and then print them
- Each insertion operation costs , pushing the final complexity to
C++14
// C++ implementation #include <bits/stdc++.h> using namespace std; // Function to return the set of pairs set<pair< int , int > > pairs(vector< int >& arr) { set<pair< int , int > > pairs; // find all subarrays for ( int i = 0; i < arr.size() - 1; ++i) { int maximum = max(arr[i], arr[i + 1]), secondmax = min(arr[i], arr[i + 1]); for ( int j = i + 1; j < arr.size(); ++j) { // update max and second max if (arr[j] > maximum) { secondmax = maximum; maximum = arr[j]; } if (arr[j] < maximum && arr[j] > secondmax) { secondmax = arr[j]; } // insert a pair in set pairs.insert(make_pair(secondmax, maximum)); } } return pairs; } int main() { vector< int > vec = { 1, 2, 6, 4, 5 }; set<pair< int , int > > st = pairs(vec); cout << "Total Number of valid pairs is :" << ( int )st.size() << "\n" ; for ( auto & x : st) { cout << "(" << x.first << ", " << x.second << ") " ; } return 0; } |
Java
// Java implementation import java.util.HashSet; import java.util.Set; class Pair implements Comparable<Pair> { int first, second; public Pair( int first, int second) { this .first = first; this .second = second; } @Override public int hashCode() { return 31 * first + second; } public boolean equals(Object p) { Pair pair = (Pair)p; if ( this .first != pair.first) return false ; return this .second == pair.second; } @Override public int compareTo(Pair p) { if ( this .first == p.first) { return this .second - p.second; } return this .first - p.first; } } public class GFG { // Function to return the set of pairs static Set<Pair> pairs( int [] arr) { Set<Pair> pairs = new HashSet<>(); // Find all subarrays for ( int i = 0 ; i < arr.length - 1 ; ++i) { int maximum = Math.max(arr[i], arr[i + 1 ]), secondmax = Math.min(arr[i], arr[i + 1 ]); for ( int j = i + 1 ; j < arr.length; ++j) { // Update max and second max if (arr[j] > maximum) { secondmax = maximum; maximum = arr[j]; } if (arr[j] < maximum && arr[j] > secondmax) { secondmax = arr[j]; } // Insert a pair in set pairs.add( new Pair(secondmax, maximum)); } } return pairs; } // Driver Code public static void main(String[] args) { int [] vec = { 1 , 2 , 6 , 4 , 5 }; Set<Pair> st = pairs(vec); System.out.println( "Total Number of " + "valid pairs is :" + st.size()); for (Pair x : st) { System.out.printf( "(%d, %d)\n" , x.first, x.second); } } } // This code is contributed by sanjeev2552 |
Python3
# python3 implementation # Function to return the set of pairs def SetofPairs(arr): pairs = set () n = len (arr) # length of array # find all subarrays for i in range (n - 1 ): maximum = max (arr[i], arr[i + 1 ]) secondmax = min (arr[i], arr[i + 1 ]) for j in range (i + 1 , n): # update max and second max if (arr[j] > maximum): secondmax = maximum maximum = arr[j] if (arr[j] < maximum and arr[j] > secondmax): secondmax = arr[j] # add a pair in set pairs.add((secondmax, maximum)) return pairs # Driver code if __name__ = = "__main__" : vec = [ 1 , 2 , 6 , 4 , 5 ] st = SetofPairs(vec) print ( "Total Number of valid pairs is :" , len (st)) for x in st: print (x, end = " " ) # This code is contributed by sunilsoni10220001022000. |
Javascript
<script> // JavaScript implementation // Function to return the set of pairs function pairs(arr) { var pairs = new Set(); // find all subarrays for ( var i = 0; i < arr.length - 1; ++i) { var maximum = Math.max(arr[i], arr[i + 1]), secondmax = Math.min(arr[i], arr[i + 1]); for ( var j = i + 1; j < arr.length; ++j) { // update max and second max if (arr[j] > maximum) { secondmax = maximum; maximum = arr[j]; } if (arr[j] < maximum && arr[j] > secondmax) { secondmax = arr[j]; } // insert a pair in set pairs.add([secondmax, maximum].toString()); } } return pairs; } var vec = [1, 2, 6, 4, 5 ]; var st = pairs(vec); document.write( "Total Number of valid pairs is :" + st.size + "<br>" ); [...st].sort().forEach(x => { x = x.split( ',' ); document.write( "(" + x[0] + ", " + x[1] + ") " ) }) </script> |
C#
// C# implementation using System; using System.Collections.Generic; public class Pair : IComparable<Pair> { public int first, second; public Pair( int first, int second) { this .first = first; this .second = second; } public override int GetHashCode() { return 31 * first + second; } public override bool Equals(Object p) { Pair pair = (Pair)p; if ( this .first != pair.first) return false ; return this .second == pair.second; } public int CompareTo(Pair p) { if ( this .first == p.first) { return this .second - p.second; } return this .first - p.first; } } public class GFG { // Function to return the set of pairs static HashSet<Pair> Pairs( int [] arr) { HashSet<Pair> pairs = new HashSet<Pair>(); // Find all subarrays for ( int i = 0; i < arr.Length - 1; ++i) { int maximum = Math.Max(arr[i], arr[i + 1]), secondmax = Math.Min(arr[i], arr[i + 1]); for ( int j = i + 1; j < arr.Length; ++j) { // Update max and second max if (arr[j] > maximum) { secondmax = maximum; maximum = arr[j]; } if (arr[j] < maximum && arr[j] > secondmax) { secondmax = arr[j]; } // Insert a pair in set pairs.Add( new Pair(secondmax, maximum)); } } return pairs; } // Driver Code public static void Main(String[] args) { int [] vec = { 1, 2, 6, 4, 5 }; HashSet<Pair> st = Pairs(vec); Console.WriteLine( "Total Number of " + "valid pairs is :" + st.Count); foreach (Pair x in st) { Console.WriteLine( "({0}, {1})" , x.first, x.second); } } } |
Total Number of valid pairs is :5 (1, 2) (2, 6) (4, 5) (4, 6) (5, 6)
Complexity Analysis:
- Time Complexity: O(N^2 log(N)).
Insertion in set takes log N time. There can be at most N^2 sub-arrays. So the time Complexity is O(N^2 log N). - Auxiliary Space: O(n^2).
As extra space is required to store the elements in a set.
Efficient Approach:
- It could bring down the complexity of finding pairs to by observing that an element can form pairs with elements only till the closest element to the right which is greater than .
- To see why this holds, consider = in the next example.
Arr = {1, 4, 5, 3, 2, 1}
- It could see that is the nearest element to the right which is greater than . forms a pair considering the sub-array .
- Other sub-arrays, that start with must include . Considering one of them, if another element exists in the sub-array, then will be the pair for that sub-array.
- Else either will be formed or will be formed, where is the max element to the right of in the sub-array.
- In any cases, cannot form a pair with any element to the right of .
- Using this observation, we can implement the logic using stack which brings down the pair generation complexity to .
- Each pair can be inserted into a set for eliminating duplicates, giving a final time complexity of
Below is the implementation of the above approach:
C++
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std; // Function to return the set of pairs set<pair< int , int >> pairs(vector< int >& arr) { stack< int > st; set<pair< int , int >> pairs; // Push first element into stack st.push(arr[0]); // For each element 'X' in arr, // pop the stack while top Element // is smaller than 'X' and form a pair. // If the stack is not empty after // the previous operation, create // a pair. Push X into the stack. for ( int i = 1; i < arr.size(); ++i) { while (!st.empty() && arr[i] > st.top()) { pairs.insert(make_pair(st.top(), arr[i])); st.pop(); } if (!st.empty()) { pairs.insert(make_pair(min(st.top(), arr[i]), max(st.top(), arr[i]))); } st.push(arr[i]); } return pairs; } int main() { vector< int > vec = { 1, 2, 6, 4, 5 }; set<pair< int , int > > st = pairs(vec); cout << "Total Number of valid pairs is :" << ( int )st.size() << "\n" ; for ( auto & x : st) { cout << "(" << x.first << ", " << x.second << ") " ; } return 0; } |
Java
// Java implementation of the above approach import java.util.*; public class GFG { static class pair { int first, second; public pair( int first, int second) { this .first = first; this .second = second; } @Override public int hashCode() { final int prime = 31 ; int result = 1 ; result = prime * result + first; result = prime * result + second; return result; } @Override public boolean equals(Object obj) { if ( this == obj) return true ; if (obj == null ) return false ; if (getClass() != obj.getClass()) return false ; pair other = (pair)obj; if (first != other.first) return false ; if (second != other.second) return false ; return true ; } } // Function to return the set of pairs static HashSet<pair> pairs( int [] arr) { Stack<Integer> st = new Stack<Integer>(); HashSet<pair> pairs = new HashSet<pair>(); // Push first element into stack st.add(arr[ 0 ]); // For each element 'X' in arr, // pop the stack while top Element // is smaller than 'X' and form a pair. // If the stack is not empty after // the previous operation, create // a pair. Push X into the stack. for ( int i = 1 ; i < arr.length; ++i) { while (!st.isEmpty() && arr[i] > st.peek()) { pairs.add( new pair(st.peek(), arr[i])); st.pop(); } if (!st.isEmpty()) { pairs.add( new pair(Math.min(st.peek(), arr[i]), Math.max(st.peek(), arr[i]))); } st.add(arr[i]); } return pairs; } // Driver code public static void main(String[] args) { int [] vec = { 1 , 2 , 6 , 4 , 5 }; HashSet<pair> st = pairs(vec); System.out.print( "Total Number of valid pairs is :" + ( int )st.size() + "\n" ); for (pair x : st) { System.out.print( "(" + x.first + ", " + x.second + ") " ); } } } // This code is contributed by 29AjayKumar |
Python3
# Python3 implementation of the above approach # Function to return the set of pairs def pairs(arr) : st = []; pairs = []; # Push first element into stack st.append(arr[ 0 ]); # For each element 'X' in arr, # pop the stack while top Element # is smaller than 'X' and form a pair. # If the stack is not empty after # the previous operation, create # a pair. Push X into the stack. for i in range ( 1 , len (arr) ) : while len (st) ! = 0 and arr[i] > st[ - 1 ] : pairs.append((st[ - 1 ], arr[i])); st.pop(); if len (st) ! = 0 : pairs.append(( min (st[ - 1 ], arr[i]), max (st[ - 1 ], arr[i]))); st.append(arr[i]); return pairs; # Driver code if __name__ = = "__main__" : vec = [ 1 , 2 , 6 , 4 , 5 ]; st = pairs(vec); print ( "Total Number of valid pairs is :" , len (st)); for x in st : print ( "(" ,x[ 0 ], ", " ,x[ 1 ], ")" ,end = " " ); # This code is contributed by AnkitRai01 |
C#
using System; using System.Collections.Generic; class GFG { // Class to store the pair public class pair { public int first, second; public pair( int first, int second) { this .first = first; this .second = second; } public override int GetHashCode() { int prime = 31; int result = 1; result = prime * result + first; result = prime * result + second; return result; } public override bool Equals( object obj) { if ( this == obj) return true ; if (obj == null ) return false ; if (GetType() != obj.GetType()) return false ; pair other = (pair)obj; if (first != other.first) return false ; if (second != other.second) return false ; return true ; } } // Function to return the set of pairs static HashSet<pair> pairs( int [] arr) { Stack< int > st = new Stack< int >(); HashSet<pair> pairs = new HashSet<pair>(); // Push first element into stack st.Push(arr[0]); // For each element 'X' in arr, // pop the stack while top Element // is smaller than 'X' and form a pair. // If the stack is not empty after // the previous operation, create // a pair. Push X into the stack. for ( int i = 1; i < arr.Length; ++i) { while (st.Count != 0 && arr[i] > st.Peek()) { pairs.Add( new pair(st.Peek(), arr[i])); st.Pop(); } if (st.Count != 0) { pairs.Add( new pair(Math.Min(st.Peek(), arr[i]), Math.Max(st.Peek(), arr[i]))); } st.Push(arr[i]); } return pairs; } // Driver code public static void Main(String[] args) { int [] vec = { 1, 2, 6, 4, 5 }; HashSet<pair> st = pairs(vec); Console.Write( "Total Number of valid pairs is :" + ( int )st.Count + "\n" ); foreach (pair x in st) { Console.Write( "(" + x.first + ", " + x.second + ") " ); } } } |
Javascript
<script> // Javacript implementation of the above approach function pairs(arr) { let st = []; let pairs = new Set(); // Push first element into stack st.push(arr[0]); // For each element 'X' in arr, // pop the stack while top Element // is smaller than 'X' and form a pair. // If the stack is not empty after // the previous operation, create // a pair. Push X into the stack. for (let i = 1; i < arr.length; ++i) { while (st.length !== 0 && arr[i] > st[st.length - 1]) { pairs.add([st[st.length - 1], arr[i]]); st.pop(); } if (st.length !== 0) { pairs.add([(Math.min(st[st.length - 1], arr[i]), Math.max(st[st.length - 1], arr[i]))]); } st.push(arr[i]); } return pairs; } let vec = [1, 2, 6, 4, 5]; let st = pairs(vec); console.log(`Total Number of valid pairs is : ${st.size}`); for (let x of st) { console.log(`(${x[0]}, ${x[1]})`); } // this code is contributed by bhardwajji </script> |
Total Number of valid pairs is :5 (1, 2) (2, 6) (4, 5) (4, 6) (5, 6)
Complexity Analysis:
- Time Complexity: O(N log(N)).
Each pair can be inserted into a set for eliminating duplicates, giving a final time complexity of O(N log N) - Auxiliary Space: O(N).
As extra space is required to store the elements in a set.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!