📌  相关文章
📜  检查是否可以使用三重循环移位对递减数组进行排序

📅  最后修改于: 2021-10-25 06:51:04             🧑  作者: Mango

给定一个大小为Narr[] ,其元素按降序排序。任务是通过执行最少数量的三重循环右交换来查找给定数组是否可以按升序排序。打印每个三重循环右交换中涉及的索引。

注意:以下示例具有基于 1 的索引。
例子:

方法:
应提出以下意见:

  • 对于具有 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,则
    1. 打印
    2. 打印floor(N / 2) 的值,因为 floor(N / 2) 是要执行的循环右交换操作的数量。
    3. 将变量K初始化为 1。
    4. 循环右交换操作只能成对执行。这些对是[K, K+1, N][K+1, N, N-1]。打印对后,将 K 的值增加 2,并将 N 的值减少 2。
    5. 继续执行第 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)