Find array with k number of merge sort calls
Given two numbers n and k, find an array containing values in [1, n] and requires exactly k calls of recursive merge sort function.
Examples:
Input : n = 3
k = 3
Output : a[] = {2, 1, 3}
Explanation:
Here, a[] = {2, 1, 3}
First of all, mergesort(0, 3) will be called,
which then sets mid = 1 and calls mergesort(0,
1) and mergesort(1, 3), which do not perform
any recursive calls because segments (0, 1)
and (1, 3) are sorted.
Hence, total mergesort calls are 3.
Input : n = 4
k = 1
Output : a[] = {1, 2, 3, 4}
Explanation:
Here, a[] = {1, 2, 3, 4} then there will be
1 mergesort call — mergesort(0, 4), which
will check that the array is sorted and then
end.
If we have a value of k even, then there is no solution since the number of calls is always odd (one call in the beginning and each call makes either 0 or 2 recursive calls).
If k is odd, let’s try to start with a sorted permutation and try to “unsort” it. Let’s make a function unsort(l, r) that will do it. When we “unsort” a segment, we can either keep it sorted (if we already made enough calls), or make it non-sorted and then call unsort(l, mid) and unsort(mid, r), if we need more calls. When we make a segment non-sorted, it’s better to keep both halves sorted; an easy way to handle this is to swap two middle elements.
It’s easy to see that the number of unsort calls is equal to the number of mergesort calls to sort the resulting permutation, so we can use this approach to try getting exactly k calls.
Below is the code for the above problem.
CPP
#include <iostream>
using namespace std;
void unsort( int l, int r, int a[], int & k)
{
if (k < 1 || l + 1 == r)
return ;
k -= 2;
int mid = (l + r) / 2;
swap(a[mid - 1], a[mid]);
unsort(l, mid, a, k);
unsort(mid, r, a, k);
}
void arrayWithKCalls( int n, int k)
{
if (k % 2 == 0) {
cout << " NO SOLUTION " ;
return ;
}
int a[n+1];
a[0] = 1;
for ( int i = 1; i < n; i++)
a[i] = i + 1;
k--;
unsort(0, n, a, k);
for ( int i = 0; i < n; ++i)
cout << a[i] << ' ' ;
}
int main()
{
int n = 10, k = 17;
arrayWithKCalls(n, k);
return 0;
}
|
Java
class GFG {
static void unsort( int l, int r, int a[], int k)
{
if (k < 1 || l + 1 == r)
return ;
k -= 2 ;
int mid = (l + r) / 2 ;
int temp = a[mid - 1 ];
a[mid - 1 ] = a[mid];
a[mid] = temp;
unsort(l, mid, a, k);
unsort(mid, r, a, k);
}
static void arrayWithKCalls( int n, int k)
{
if (k % 2 == 0 ) {
System.out.print( "NO SOLUTION" );
return ;
}
int a[] = new int [n + 1 ];
a[ 0 ] = 1 ;
for ( int i = 1 ; i < n; i++)
a[i] = i + 1 ;
k--;
unsort( 0 , n, a, k);
for ( int i = 0 ; i < n; ++i)
System.out.print(a[i] + " " );
}
public static void main(String[] args)
{
int n = 10 , k = 17 ;
arrayWithKCalls(n, k);
}
}
|
Python3
def unsort(l,r,a,k):
if (k < 1 or l + 1 = = r):
return
k - = 2
mid = (l + r) / / 2
temp = a[mid - 1 ]
a[mid - 1 ] = a[mid]
a[mid] = temp
unsort(l, mid, a, k)
unsort(mid, r, a, k)
def arrayWithKCalls(n,k):
if (k % 2 = = 0 ):
print ( "NO SOLUTION" )
return
a = [ 0 for i in range (n + 2 )]
a[ 0 ] = 1
for i in range ( 1 , n):
a[i] = i + 1
k - = 1
unsort( 0 , n, a, k)
for i in range (n):
print (a[i] , " " ,end = "")
n = 10
k = 17
arrayWithKCalls(n, k)
|
C#
using System;
class GFG {
static void unsort( int l, int r,
int []a, int k)
{
if (k < 1 || l + 1 == r)
return ;
k -= 2;
int mid = (l + r) / 2;
int temp = a[mid - 1];
a[mid - 1] = a[mid];
a[mid] = temp;
unsort(l, mid, a, k);
unsort(mid, r, a, k);
}
static void arrayWithKCalls( int n, int k)
{
if (k % 2 == 0)
{
Console.WriteLine( "NO SOLUTION" );
return ;
}
int []a = new int [n + 1];
a[0] = 1;
for ( int i = 1; i < n; i++)
a[i] = i + 1;
k--;
unsort(0, n, a, k);
for ( int i = 0; i < n; ++i)
Console.Write(a[i] + " " );
}
public static void Main()
{
int n = 10, k = 17;
arrayWithKCalls(n, k);
}
}
|
Javascript
<script>
var k;
function unsort(l, r, a)
{
if (k < 1 || l + 1 == r)
return ;
k -= 2;
var mid = parseInt((l + r) / 2);
[a[mid - 1], a[mid]] = [a[mid], a[mid - 1]];
unsort(l, mid, a);
unsort(mid, r, a);
}
function arrayWithKCalls(n)
{
if (k % 2 == 0) {
document.write( " NO SOLUTION " );
return ;
}
var a = Array(n+1);
a[0] = 1;
for ( var i = 1; i < n; i++)
a[i] = i + 1;
k--;
unsort(0, n, a);
for ( var i = 0; i < n; ++i)
document.write( a[i] + ' ' );
}
var n = 10
k = 17;
arrayWithKCalls(n);
</script>
|
Output
3 1 4 6 2 8 5 9 7 10
Time Complexity: O(n*log(n))
Auxiliary Space: O(n)
Last Updated :
23 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...