Given an array arr[] containing a permutation of first N natural numbers. In one operation, remove a pair (X, Y) from the array and insert (X + Y + 1) / 2 into the array. The task is to find the smallest array element that can be left remaining in the array by performing the given operation exactly N – 1 times and the N – 1 pairs. If multiple solutions exist, then print any one of them.
Examples:
Input: arr[] = {1, 2, 3, 4}
Output: {2}, { (2, 4), (3, 3), (1, 3) }
Explanation:
Selecting a pair(arr[1], arr[3]) modifies the array arr[] = {1, 3, 3}
Selecting a pair(arr[1], arr[2]) modifies the array arr[] = {1, 3}
Selecting a pair(arr[0], arr[1]) modifies the array arr[] = {2}
Therefore, the smallest element left in array = {2} and the pairs that can be selected are {(2, 4), (3, 3), (1, 3)}.
Input: arr[] = {3, 2, 1}
Output: {2}, { (3, 2), (3, 1) }
Approach:The problem can be solved using Greedy technique. Follow the steps below to solve the problem:
- Initialize an array, say pairsArr[] to store all the pairs that can be selected by performing the given operations.
- Create a priority queue, say pq to store all the array elements in the priority queue.
- Traverse pq while count elements left in pq is greater than 1 and in each operation pop the top two elements(X, Y) of pq, store (X, Y) in pairsArr[] and insert an element having the value (X + Y + 1) / 2 in pq.
- Finally, print the value of the element left in pq and pairsArr[].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void smallestNumberLeftInPQ( int arr[], int N)
{
priority_queue< int > pq;
vector<pair< int , int > > pairsArr;
for ( int i = 0; i < N; i++) {
pq.push(arr[i]);
}
while (pq.size() > 1) {
int X = pq.top();
pq.pop();
int Y = pq.top();
pq.pop();
pq.push((X + Y + 1) / 2);
pairsArr.push_back({ X, Y });
}
cout << "{" << pq.top() << "}, " ;
int sz = pairsArr.size();
for ( int i = 0; i < sz; i++) {
if (i == 0) {
cout << "{ " ;
}
cout << "(" << pairsArr[i].first
<< ", " << pairsArr[i].second << ")" ;
if (i != sz - 1) {
cout << ", " ;
}
if (i == sz - 1) {
cout << " }" ;
}
}
}
int main()
{
int arr[] = { 3, 2, 1 };
int N = sizeof (arr) / sizeof (arr[0]);
smallestNumberLeftInPQ(arr, N);
}
|
Java
import java.util.*;
class GFG
{
static class pair
{
int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static void smallestNumberLeftInPQ( int arr[], int N)
{
PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) ->
Integer.compare(y, x));
Vector<pair > pairsArr = new Vector<>();
for ( int i = 0 ; i < N; i++)
{
pq.add(arr[i]);
}
while (pq.size() > 1 ) {
int X = pq.peek();
pq.remove();
int Y = pq.peek();
pq.remove();
pq.add((X + Y + 1 ) / 2 );
pairsArr.add( new pair( X, Y ));
}
System.out.print( "{" + pq.peek()+ "}, " );
int sz = pairsArr.size();
for ( int i = 0 ; i < sz; i++) {
if (i == 0 ) {
System.out.print( "{ " );
}
System.out.print( "(" + pairsArr.get(i).first
+ ", " + pairsArr.get(i).second+ ")" );
if (i != sz - 1 ) {
System.out.print( ", " );
}
if (i == sz - 1 ) {
System.out.print( " }" );
}
}
}
public static void main(String[] args)
{
int arr[] = { 3 , 2 , 1 };
int N = arr.length;
smallestNumberLeftInPQ(arr, N);
}
}
|
Python3
def smallestNumberLeftInPQ(arr, N):
pq = []
pairsArr = []
for i in range (N):
pq.append(arr[i])
pq = sorted (pq)
while ( len (pq) > 1 ):
X = pq[ - 1 ]
del pq[ - 1 ]
Y = pq[ - 1 ]
del pq[ - 1 ]
pq.append((X + Y + 1 ) / / 2 )
pairsArr.append([X, Y])
pq = sorted (pq)
print ( "{" , pq[ - 1 ], "}, " ,
end = "")
sz = len (pairsArr)
for i in range (sz):
if (i = = 0 ):
print ( "{ " , end = "")
print ( "(" , pairsArr[i][ 0 ], "," ,
pairsArr[i][ 1 ], ")" , end = "")
if (i ! = sz - 1 ):
print (end = ", " )
if (i = = sz - 1 ):
print (end = " }" )
if __name__ = = '__main__' :
arr = [ 3 , 2 , 1 ]
N = len (arr)
smallestNumberLeftInPQ(arr, N)
|
C#
using System;
using System.Collections.Generic;
class GFG{
public class pair
{
public int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static void smallestNumberLeftInPQ( int [] arr,
int N)
{
List< int > pq = new List< int >();
List<pair> pairsArr = new List<pair>();
for ( int i = 0; i < N; i++)
{
pq.Add(arr[i]);
}
pq.Sort();
pq.Reverse();
while (pq.Count > 1)
{
int X = pq[0];
pq.RemoveAt(0);
int Y = pq[0];
pq.RemoveAt(0);
pq.Add((X + Y + 1) / 2);
pq.Sort();
pq.Reverse();
pairsArr.Add( new pair(X, Y));
}
Console.Write( "{" + pq[0] + "}, " );
int sz = pairsArr.Count;
for ( int i = 0; i < sz; i++)
{
if (i == 0)
{
Console.Write( "{ " );
}
Console.Write( "(" + pairsArr[i].first + ", " +
pairsArr[i].second + ")" );
if (i != sz - 1)
{
Console.Write( ", " );
}
if (i == sz - 1)
{
Console.Write( " }" );
}
}
}
public static void Main(String[] args)
{
int [] arr = { 3, 2, 1 };
int N = arr.Length;
smallestNumberLeftInPQ(arr, N);
}
}
|
Javascript
<script>
class pair
{
constructor(first,second)
{
this .first = first;
this .second = second;
}
}
function smallestNumberLeftInPQ(arr,N)
{
let pq = [];
let pairsArr = [];
for (let i = 0; i < N; i++)
{
pq.push(arr[i]);
}
pq.sort( function (a,b){ return b-a;});
while (pq.length > 1) {
let X = pq[0];
pq.shift();
let Y = pq[0];
pq.shift();
pq.push(Math.floor((X + Y + 1) / 2));
pq.sort( function (a,b){ return b-a;});
pairsArr.push( new pair( X, Y ));
}
document.write( "{" + pq[0]+ "}, " );
let sz = pairsArr.length;
for (let i = 0; i < sz; i++) {
if (i == 0) {
document.write( "{ " );
}
document.write( "(" + pairsArr[i].first
+ ", " + pairsArr[i].second+ ")" );
if (i != sz - 1) {
document.write( ", " );
}
if (i == sz - 1) {
document.write( " }" );
}
}
}
let arr=[3, 2, 1 ];
let N = arr.length;
smallestNumberLeftInPQ(arr, N);
</script>
|
Output: {2}, { (3, 2), (3, 1) }
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)