给定大小为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模4的值为2或3,则打印NO 。
- 如果N模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,直到打印了所有floor(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
YES
2
1 2 5
2 5 4
时间复杂度: O(N)
辅助空间: O(1)