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

📅  最后修改于: 2021-05-17 22:17:36             🧑  作者: 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模4的值为2或3,则打印NO
  • 如果N模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,直到打印了所有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)