给定一个大小为N的arr[] ,其元素按降序排序。任务是通过执行最少数量的三重循环右交换来查找给定数组是否可以按升序排序。打印每个三重循环右交换中涉及的索引。
Triple Cyclic Right Swap refers to the triple cyclic right shift in which:
arr[i] -> arr[j] -> arr[k] -> arr[i], where 0 <= i, j, k < N and i, j and k must be different.
注意:以下示例具有基于 1 的索引。
例子:
Input: arr[] = {100, 90, 80, 70, 60}
Output: YES
2
[1 2 5]
[2 5 4]
Explanation:
For the first operation the indexes chosen are 1, 2 and 5.
arr[1] = arr[5] = 60
arr[2] = arr[1] = 100
arr[5] = arr[2] = 90
The updated array after 1st cyclic right shift is {60 100 80 70 90}
For the first operation the indexes chosen are 2, 5 and 4.
arr[2] = arr[4] = 70
arr[5] = arr[2] = 100
arr[4] = arr[5] = 90
The updated array after 2nd cyclic right shift is {60 70 80 90 100}
Thus the array is sorted by just 2 cyclic right swap operations.
Input: arr[] = {7, 6, 5, 4, 3, 2, 1}
Output: NO
Explanation:
It is not possible to perform any cyclic right shift operation on this array and thus it cannot be sorted in ascending order.
方法:
应提出以下意见:
- 对于具有 3 个元素的数组,答案是否定的。因为中间元素处于正确的位置,我们将剩下两个元素,而循环右移需要三个元素。
- 如果(N % 4) == 0或(N % 4) == 1则可以排序,否则无法排序。
从上面的方法可以看出,每两次循环右移就有四个元素被排序。 - 当N % 4 == 0 时:
让我们考虑数组 [4 3 2 1]。在索引 1 2 4 和 2 4 3 (按顺序)两次移位后,数组被排序为 1 2 3 4。 - 当N % 4 == 1 时:
上面提到的使用数组中的 5 个元素的示例 1 是适用的。索引 3 处的元素保持原样,而其他 4 个元素按 2 次循环右移排序。 - 当N % 4 == 2 时:
无法对数组进行排序,因为在对 4 个元素的组进行排序后,最后 2 个元素将以不正确的顺序留下,这永远无法排序,因为需要精确排序 3 个元素。 - 当N % 4 == 3 时:
不可能对数组进行排序,因为在 4 个元素的组之后,最后 3 个元素将以不正确的顺序留下,永远无法排序,因为这 3 个未排序元素中的中间元素从一开始就保持在正确的位置。这给我们留下了 2 个永远无法排序的元素,因为恰好需要 3 个元素进行排序。
请按照以下步骤解决问题。
- 如果 N modulo 4 的值为 2 或 3,则打印NO 。
- 如果 N modulo 4 的值是 0 或 1,则
- 打印是
- 打印floor(N / 2) 的值,因为 floor(N / 2) 是要执行的循环右交换操作的数量。
- 将变量K初始化为 1。
- 循环右交换操作只能成对执行。这些对是[K, K+1, N]和[K+1, N, N-1]。打印对后,将 K 的值增加 2,并将 N 的值减少 2。
- 继续执行第 4 步,直到打印出所有的楼层(N/2)操作。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
void sortarray(int arr[],int N)
{
// If array is 3 2 1 can't
// be sorted because 2 is in
// its correct position, 1
// and 3 can't shift right
// because cyclic right shift
// takes place between 3 elements
if(N == 3)
cout << "NO" << endl;
// Check if its possible to sort
else if(N % 4 == 0 || N % 4 == 1)
{
cout << "YES" << endl;
// Number of swap is
// N / 2 always
// for this approach
cout << (N / 2) << endl;
int k = 1;
// Printing index of the
// cyclic right shift
for(int l = 0; l < (N / 4); l++)
{
cout << k << " " << k + 1
<< " " << N << endl;
cout << k + 1 << " " << N
<< " " << N - 1 << endl;
k = k + 2;
N = N - 2;
}
}
else
cout << "NO" << endl;
}
// Driver code
int main()
{
int N = 5;
int arr[] = { 5, 4, 3, 2, 1 };
sortarray(arr, N);
return 0;
}
// This code is contributed by divyeshrabadiya07
Java
// Java program for the above approach
class GFG{
static void sortarray(int arr[], int N)
{
// If array is 3 2 1 can't
// be sorted because 2 is in
// its correct position, 1
// and 3 can't shift right
// because cyclic right shift
// takes place between 3 elements
if(N == 3)
System.out.println("NO");
// Check if its possible to sort
else if(N % 4 == 0 || N % 4 == 1)
{
System.out.println("YES");
// Number of swap is
// N / 2 always
// for this approach
System.out.println(N / 2);
int k = 1, l;
// Printing index of the
// cyclic right shift
for(l = 0; l < (N / 4); l++)
{
System.out.println(k + " " + (k + 1) +
" " + N);
System.out.println(k + 1 + " " +
N + " " + (N - 1));
k = k + 2;
N = N - 2;
}
}
else
System.out.println("NO");
}
// Driver code
public static void main (String []args)
{
int N = 5;
int arr[] = { 5, 4, 3, 2, 1 };
sortarray(arr, N);
}
}
// This code is contributed by chitranayal
Python3
# Python3 program for the above approach
def sortarray(arr, N):
# if array is 3 2 1 can't
# be sorted because 2 is in
# its correct position, 1
# and 3 can't shift right
# because cyclic right shift
# takes place between 3 elements
if(N == 3):
print("NO")
# check if its possible to sort
elif(N % 4 == 0
or N % 4 == 1):
print("YES")
# Number of swap is
# N / 2 always
# for this approach
print(N // 2)
k = 1
# printing index of the
# cyclic right shift
for l in range(N // 4):
print(k, k + 1, N)
print(k + 1, N, N-1)
k = k + 2
N = N - 2
else:
print("NO")
# Driver code
if __name__ == "__main__":
N = 5
arr = [5, 4, 3, 2, 1]
sortarray(arr, N)
C#
// C# program for the above approach
using System;
class GFG{
static void sortarray(int[] arr, int N)
{
// If array is 3 2 1 can't
// be sorted because 2 is in
// its correct position, 1
// and 3 can't shift right
// because cyclic right shift
// takes place between 3 elements
if(N == 3)
Console.WriteLine("NO");
// Check if its possible to sort
else if(N % 4 == 0 || N % 4 == 1)
{
Console.WriteLine("YES");
// Number of swap is
// N / 2 always
// for this approach
Console.WriteLine(N / 2);
int k = 1;
// Printing index of the
// cyclic right shift
for(int l = 0; l < (N / 4); l++)
{
Console.WriteLine(k + " " + (k + 1) +
" " + N);
Console.WriteLine(k + 1 + " " + N +
" " + (N - 1));
k = k + 2;
N = N - 2;
}
}
else
Console.WriteLine("NO");
}
// Driver code
public static void Main()
{
int N = 5;
int []arr = { 5, 4, 3, 2, 1 };
sortarray(arr, N);
}
}
// This code is contributed by sanjoy_62
Javascript
YES
2
1 2 5
2 5 4
时间复杂度: O(N)
辅助空间: O(1)