Skip to content
Related Articles

Related Articles

Improve Article

Find array with k number of merge sort calls

  • Difficulty Level : Hard
  • Last Updated : 28 May, 2021

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.

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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




// C++ program to find an array that can be
// sorted with k merge sort calls.
#include <iostream>
using namespace std;
 
void unsort(int l, int r, int a[], int& k)
{
    if (k < 1 || l + 1 == r)
        return;
 
    // We make two recursive calls, so
    // reduce k by 2.
    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;
    }
 
    // Create an array with values
    // in [1, n]
    int a[n+1];
    a[0] = 1;
    for (int i = 1; i < n; i++)
        a[i] = i + 1;
    k--;
 
    // calling unsort function
    unsort(0, n, a, k);
 
    for (int i = 0; i < n; ++i)
        cout << a[i] << ' ';
}
 
// Driver code
int main()
{
    int n = 10, k = 17;
    arrayWithKCalls(n, k);
    return 0;
}

Java




// Java program to find an array that can be
// sorted with k merge sort calls.
class GFG {
     
    static void unsort(int l, int r, int a[], int k)
    {
         
        if (k < 1 || l + 1 == r)
            return;
 
        // We make two recursive calls, so
        // reduce k by 2.
        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;
        }
 
        // Create an array with values
        // in [1, n]
        int a[] = new int[n + 1];
        a[0] = 1;
         
        for (int i = 1; i < n; i++)
            a[i] = i + 1;
        k--;
 
        // calling unsort function
        unsort(0, n, a, k);
 
        for (int i = 0; i < n; ++i)
            System.out.print(a[i] + " ");
    }
     
    // Driver code
    public static void main(String[] args)
    {
         
        int n = 10, k = 17;
         
        arrayWithKCalls(n, k);
    }
}
 
// This code is contributed by Anant Agarwal.

Python3




# Python program to find
# an array that can be
# sorted with k merge
# sort calls.
 
def unsort(l,r,a,k):
 
    if (k < 1 or l + 1 == r):
        return
  
    # We make two recursive calls, so
    # reduce k by 2.
    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
     
  
    # Create an array with values
    # in [1, n]
    a = [0 for i in range(n + 2)]
    a[0] = 1
    for i in range(1, n):
        a[i] = i + 1
    k-=1
  
    # calling unsort function
    unsort(0, n, a, k)
  
    for i in range(n):
        print(a[i] ," ",end="")
 
# Driver code
 
n = 10
k = 17
arrayWithKCalls(n, k)
 
# This code is contributed
# by Anant Agarwal.

C#




// C# program to find an array that can
// be sorted with k merge sort calls.
using System;
 
class GFG {
     
    static void unsort(int l, int r,
                       int []a, int k)
    {
        if (k < 1 || l + 1 == r)
            return;
 
        // We make two recursive calls,
        // so reduce k by 2.
        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;
        }
 
        // Create an array with
        // values in [1, n]
        int []a = new int[n + 1];
        a[0] = 1;
         
        for (int i = 1; i < n; i++)
            a[i] = i + 1;
        k--;
 
        // calling unsort function
        unsort(0, n, a, k);
 
        for (int i = 0; i < n; ++i)
            Console.Write(a[i] + " ");
    }
     
    // Driver code
    public static void Main()
    {
         
        int n = 10, k = 17;
         
        arrayWithKCalls(n, k);
    }
}
 
// This code is contributed by vt_m.

Javascript




<script>
 
// JavaScript program to find an array that can be
// sorted with k merge sort calls.
 
var k;
 
function unsort(l, r, a)
{
    if (k < 1 || l + 1 == r)
        return;
 
    // We make two recursive calls, so
    // reduce k by 2.
    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;
    }
 
    // Create an array with values
    // in [1, n]
    var a = Array(n+1);
    a[0] = 1;
    for (var i = 1; i < n; i++)
        a[i] = i + 1;
    k--;
 
    // calling unsort function
    unsort(0, n, a);
 
    for (var i = 0; i < n; ++i)
        document.write( a[i] + ' ');
}
 
// Driver code
var n = 10
k = 17;
arrayWithKCalls(n);
 
</script>

Output:  

3 1 4 6 2 8 5 9 7 10

 




My Personal Notes arrow_drop_up
Recommended Articles
Page :