📜  查找具有k个合并排序调用的数组

📅  最后修改于: 2021-04-29 08:53:39             🧑  作者: Mango

给定两个数字n和k,找到一个包含[1,n]中值的数组,并且需要k个递归合并排序函数。

例子:

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.

如果我们的k值为偶数,则没有解决方案,因为调用数始终为奇数(开头有一个调用,每个调用进行0或2个递归调用)。

如果k为奇数,让我们尝试从排序的序列开始,然后尝试对其进行“取消排序”。让我们将一个函数unsort(l,r)做到这一点。当我们“细分”细分时,如果需要更多信息,我们可以保持其分类(如果我们已经进行了足够的调用),也可以使其不进行分类,然后调用unsort(l,mid)和unsort(mid,r)。电话。当我们将细分设为未排序时,最好将其两半都排序。一种简单的处理方法是交换两个中间元素。

可以很容易地看到,未排序调用的数量等于对排序结果进行排序的mergesort调用的数量,因此我们可以使用这种方法尝试准确地获取k个调用。

下面是上述问题的代码。

CPP
// C++ program to find an array that can be
// sorted with k merge sort calls.
#include 
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.


输出:

3 1 4 6 2 8 5 9 7 10