给定两个数字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