Open In App

Sort a permutation of first N Natural Numbers by swapping pairs satisfying given conditions

Last Updated : 29 Jul, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array p[] of size N representing a permutation of first N natural numbers, where N is an even number, the task is to sort the array by taking a pair of indices a, b and swap p[a] and p[b] in each operation, where 2 * |a – b| ? N. Print the pairs of indices swapped in each operation.

Examples:

Input: p[] = {2, 5, 3, 1, 4, 6}
Output: 3
1 5
2 5
1 4
Explanation:
Operation 1: Swap p[1] and p[5]. Therefore, p[] modifies to {4, 5, 3, 1, 2, 6}. 
Operation 2: Swap p[2] and p[5]. Therefore, p[] modifies to {4, 2, 3, 1, 5, 6}.
Operation 3: Swap p[1] and p[4]. Therefore, p[] modifies to {1, 2, 3, 4, 5, 6}.
Therefore, the array is sorted.

Input: p[] = {1, 2, 3, 4}
Output: 0

Approach: Follow the steps below to solve the problem:

  • Create an array, posOfCurrNum[] that stores the position of the numbers present in p[].
  • Iterate in the range [1, N] using the variable i and set posOfCurrNum[p[i]] to i.
  • Declare a vector of pair ans to store the swaps that are to be performed to sort the given array p[].
  • Iterate in the range [1, N] using the variable i
    • If p[i] equal to i, then that means the current number i is already present at the right position. So, continue to the next iteration.
    • Initialize a variable j with posOfCurrNum[i] to store the current position of the number i.
    • Now, arises 4 cases:
      • Case 1: If |i – j| * 2 is greater than n, then, swap(i, j) and store this pair in ans.
      • Case 2: if n/2 is less than or equal to i – 1, then, swap(i, 1) ? swap(1, j) ? swap(i, 1) and store these pair in ans.
      • Case 3: if n/2 is less than or equal to n – j, then, swap(i, n) ? swap(j, n) ? swap(i, n) and store these pair in ans.
      • Case 4: if n/2 is less than j -1 and n/2 is less than or equal to n – i, then swap(i, n) ? swap(n, 1) ? swap(1, j) ? swap(1, n) ? swap(i, n) and store these pair in ans.
  • Print the size of the vector, ans.
  • Traverse the vector of pairs, ans, and print each pair.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to swap integers
// in an operation
void Swap(int x, int y, int p[],
          int posOfCurrNum[])
{
    swap(posOfCurrNum[p[x]],
         posOfCurrNum[p[y]]);
 
    swap(p[x], p[y]);
}
 
// Function to sort permutation
// using given operations
void sortArray(int p[], int n)
{
    // Store the position of the
    // array elements
    int posOfCurrNum[n + 1];
    for (int i = 1; i <= n; i++) {
        posOfCurrNum[p[i]] = i;
    }
 
    // Store the result
    vector<pair<int, int> > ans;
 
    // Traverse the given array, p[]
    for (int i = 1; i <= n; i++) {
 
        // If current number is already
        // present at the right position
        if (p[i] == i) {
            continue;
        }
 
        // Store the current position of
        // the number 'i'
        int j = posOfCurrNum[i];
 
        // Case 1: If both the indices
        // satisfies the given condition
        if (abs(i - j) * 2 >= n) {
 
            Swap(i, j, p, posOfCurrNum);
 
            ans.push_back({ i, j });
        }
 
        // Case 2: If the current number
        // 'i' is present at right side
        // of half of the given array
        else if (n / 2 <= i - 1) {
 
            Swap(1, i, p, posOfCurrNum);
            ans.push_back({ i, 1 });
 
            Swap(1, j, p, posOfCurrNum);
            ans.push_back({ 1, j });
 
            Swap(i, 1, p, posOfCurrNum);
            ans.push_back({ i, 1 });
        }
 
        // Case 3: If the position of the
        // current number 'i' is left side
        // of half of the given array
        else if (n - j >= n / 2) {
 
            Swap(i, n, p, posOfCurrNum);
            ans.push_back({ i, n });
 
            Swap(j, n, p, posOfCurrNum);
            ans.push_back({ j, n });
 
            Swap(i, n, p, posOfCurrNum);
            ans.push_back({ i, n });
        }
 
        // Case 4: For all other cases
        else {
            Swap(i, n, p, posOfCurrNum);
            ans.push_back({ i, n });
 
            Swap(n, 1, p, posOfCurrNum);
            ans.push_back({ n, 1 });
 
            Swap(1, j, p, posOfCurrNum);
            ans.push_back({ 1, j });
 
            Swap(1, n, p, posOfCurrNum);
            ans.push_back({ 1, n });
 
            Swap(i, n, p, posOfCurrNum);
            ans.push_back({ i, n });
        }
    }
 
    // Print the number of operations
    cout << ans.size() << '\n';
 
    // Print the steps
    for (auto p : ans)
        cout << p.first << " "
             << p.second << '\n';
}
 
// Driver Code
int main()
{
 
    // Given Input
    int n = 6;
 
    // Append 0 to consider
    // 1-based indexing
    int p[] = { 0, 2, 5, 3, 1, 4, 6 };
 
    // Function Call
    sortArray(p, n);
 
    return 0;
}


Java




// Java program for the above approach
import java.lang.*;
import java.util.*;
 
class pair
{
  int first, second;
  pair(int first, int second)
  {
    this.first = first;
    this.second = second;
  }
}
class GFG
{
   
  // Function to swap integers
  // in an operation
  static void Swap(int x, int y, int p[],
                   int posOfCurrNum[])
  {
    int t1 = posOfCurrNum[p[x]];
    posOfCurrNum[p[x]] = posOfCurrNum[p[y]];
    posOfCurrNum[p[y]] = t1;
 
    int t2 = p[x];
    p[x] = p[y];
    p[y] = t2;
  }
 
  // Function to sort permutation
  // using given operations
  static void sortArray(int p[], int n)
  {
    // Store the position of the
    // array elements
    int[] posOfCurrNum = new int[n + 1];
    for (int i = 1; i <= n; i++) {
      posOfCurrNum[p[i]] = i;
    }
 
    // Store the result
    ArrayList<pair > ans=new ArrayList<>();
 
    // Traverse the given array, p[]
    for (int i = 1; i <= n; i++) {
 
      // If current number is already
      // present at the right position
      if (p[i] == i) {
        continue;
      }
 
      // Store the current position of
      // the number 'i'
      int j = posOfCurrNum[i];
 
      // Case 1: If both the indices
      // satisfies the given condition
      if (Math.abs(i - j) * 2 >= n) {
 
        Swap(i, j, p, posOfCurrNum);
 
        ans.add(new pair( i, j ));
      }
 
      // Case 2: If the current number
      // 'i' is present at right side
      // of half of the given array
      else if (n / 2 <= i - 1) {
 
        Swap(1, i, p, posOfCurrNum);
        ans.add(new pair( i, 1 ));
 
        Swap(1, j, p, posOfCurrNum);
        ans.add(new pair( 1, j ));
 
        Swap(i, 1, p, posOfCurrNum);
        ans.add(new pair( i, 1 ));
      }
 
      // Case 3: If the position of the
      // current number 'i' is left side
      // of half of the given array
      else if (n - j >= n / 2) {
 
        Swap(i, n, p, posOfCurrNum);
        ans.add(new pair( i, n ));
 
        Swap(j, n, p, posOfCurrNum);
        ans.add(new pair( j, n ));
 
        Swap(i, n, p, posOfCurrNum);
        ans.add(new pair( i, n ));
      }
 
      // Case 4: For all other cases
      else {
        Swap(i, n, p, posOfCurrNum);
        ans.add(new pair( i, n ));
 
        Swap(n, 1, p, posOfCurrNum);
        ans.add(new pair( n, 1 ));
 
        Swap(1, j, p, posOfCurrNum);
        ans.add(new pair( 1, j ));
 
        Swap(1, n, p, posOfCurrNum);
        ans.add(new pair( 1, n ));
 
        Swap(i, n, p, posOfCurrNum);
        ans.add(new pair( i, n ));
      }
    }
 
    // Print the number of operations
    System.out.println(ans.size());
 
    // Print the steps
    for (pair pp : ans)
      System.out.println(pp.first+" "+pp.second);
  }
   
  // Driver code
  public static void main(String[] args)
  {
 
    // Given Input
    int n = 6;
 
    // Append 0 to consider
    // 1-based indexing
    int p[] = { 0, 2, 5, 3, 1, 4, 6 };
 
    // Function Call
    sortArray(p, n);
 
  }
}
 
// This code is contributed by offbeat


Python3




# Python3 program for the above approach
 
# Function to swap integers
# in an operation
def Swap(x, y, p, posOfCurrNum):
     
    posOfCurrNum[p[x]], posOfCurrNum[p[y]] = posOfCurrNum[p[y]], posOfCurrNum[p[x]]
 
    p[x], p[y] = p[y], p[x]
    return p, posOfCurrNum
 
# Function to sort permutation
# using given operations
def sortArray(p, n):
     
    # Store the position of the
    # array elements
    posOfCurrNum = [0] * (n + 1)
    for i in range(1, n + 1):
        posOfCurrNum[p[i]] = i
 
    # Store the result
    ans = []
 
    # Traverse the given array, p[]
    for i in range(1, n + 1):
         
        # If current number is already
        # present at the right position
        if (p[i] == i):
            continue
 
        # Store the current position of
        # the number 'i'
        j = posOfCurrNum[i]
 
        # Case 1: If both the indices
        # satisfies the given condition
        if (abs(i - j) * 2 >= n):
            p, posOfCurrNum = Swap(i, j, p, posOfCurrNum)
 
            ans.append([i, j])
             
        # Case 2: If the current number
        # 'i' is present at right side
        # of half of the given array
        elif (n // 2 <= i - 1):
            p, posOfCurrNum = Swap(1, i, p, posOfCurrNum)
            ans.append([i, 1])
 
            p, posOfCurrNum = Swap(1, j, p, posOfCurrNum)
            ans.append([1, j])
 
            p, posOfCurrNum = Swap(i, 1, p, posOfCurrNum)
            ans.append([i, 1])
 
        # Case 3: If the position of the
        # current number 'i' is left side
        # of half of the given array
        elif (n - j >= n // 2):
            p, posOfCurrNum = Swap(i, n, p, posOfCurrNum)
            ans.append([i, n])
 
            p, posOfCurrNum = Swap(j, n, p, posOfCurrNum)
            ans.append([j, n])
 
            p, posOfCurrNum = Swap(i, n, p, posOfCurrNum)
            ans.append([i, n])
             
        # Case 4: For all other cases
        else:
            p, posOfCurrNum = Swap(i, n, p, posOfCurrNum)
            ans.append([i, n])
 
            p, posOfCurrNum = Swap(n, 1, p, posOfCurrNum)
            ans.append([n, 1])
 
            p, posOfCurrNum = Swap(1, j, p, posOfCurrNum)
            ans.append([1, j])
 
            p, posOfCurrNum = Swap(1, n, p, posOfCurrNum)
            ans.append([1, n])
 
            p, posOfCurrNum = Swap(i, n, p, posOfCurrNum)
            ans.append([i, n])
 
    # Print the number of operations
    print(len(ans))
 
    # Print the steps
    for p in ans:
        print(p[0], p[1])
 
# Driver Code
if __name__ == '__main__':
 
    # Given Input
    n = 6
 
    # Append 0 to consider
    # 1-based indexing
    p = [ 0, 2, 5, 3, 1, 4, 6 ]
 
    # Function Call
    sortArray(p, n)
 
# This code is contributed by mohit kumar 29


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
     
  // Function to swap integers
  // in an operation
  static void Swap(int x, int y, int[] p,
                   int[] posOfCurrNum)
  {
    int t1 = posOfCurrNum[p[x]];
    posOfCurrNum[p[x]] = posOfCurrNum[p[y]];
    posOfCurrNum[p[y]] = t1;
  
    int t2 = p[x];
    p[x] = p[y];
    p[y] = t2;
  }
  
  // Function to sort permutation
  // using given operations
  static void sortArray(int[] p, int n)
  {
    // Store the position of the
    // array elements
    int[] posOfCurrNum = new int[n + 1];
    for (int i = 1; i <= n; i++) {
      posOfCurrNum[p[i]] = i;
    }
  
    // Store the result
    List<Tuple<int,int>> ans = new List<Tuple<int,int>>();
  
    // Traverse the given array, p[]
    for (int i = 1; i <= n; i++) {
  
      // If current number is already
      // present at the right position
      if (p[i] == i) {
        continue;
      }
  
      // Store the current position of
      // the number 'i'
      int j = posOfCurrNum[i];
  
      // Case 1: If both the indices
      // satisfies the given condition
      if (Math.Abs(i - j) * 2 >= n) {
  
        Swap(i, j, p, posOfCurrNum);
  
        ans.Add(new Tuple<int,int>(i, j));
      }
  
      // Case 2: If the current number
      // 'i' is present at right side
      // of half of the given array
      else if (n / 2 <= i - 1) {
  
        Swap(1, i, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(i, 1));
  
        Swap(1, j, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(1, j));
  
        Swap(i, 1, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(i, 1));
      }
  
      // Case 3: If the position of the
      // current number 'i' is left side
      // of half of the given array
      else if (n - j >= n / 2) {
  
        Swap(i, n, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(i, n));
  
        Swap(j, n, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(j, n));
  
        Swap(i, n, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(i, n));
      }
  
      // Case 4: For all other cases
      else {
        Swap(i, n, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(i, n));
  
        Swap(n, 1, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(n, 1));
  
        Swap(1, j, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(1, 4));
  
        Swap(1, n, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(1, 6));
  
        Swap(i, n, p, posOfCurrNum);
        ans.Add(new Tuple<int,int>(i, n));
      }
    }
  
    // Print the number of operations
    Console.WriteLine(ans.Count);
  
    // Print the steps
    foreach(Tuple<int,int> pp in ans)
      Console.WriteLine(pp.Item1+" "+pp.Item2);
  }
     
 // Driver code
  static void Main()
  {
     
    // Given Input
    int n = 6;
  
    // Append 0 to consider
    // 1-based indexing
    int[] p = { 0, 2, 5, 3, 1, 4, 6 };
  
    // Function Call
    sortArray(p, n);
  }
}
 
// This code is contributed by mukesh07.


Javascript




<script>
// Javascript program for the above approach
 
 
// Function to swap integers
// in an operation
function Swap(x, y, p, posOfCurrNum)
{
    let temp = posOfCurrNum[p[x]];
    posOfCurrNum[p[x]] = posOfCurrNum[p[y]];
    posOfCurrNum[p[y]] = temp;
 
     temp = p[x];
    p[x] = p[y];
    p[y] = temp;
}
 
// Function to sort permutation
// using given operations
function sortArray(p, n)
{
    // Store the position of the
    // array elements
    let posOfCurrNum = new Array(n + 1);
    for (let i = 1; i <= n; i++) {
        posOfCurrNum[p[i]] = i;
    }
 
    // Store the result
    let ans = [];
 
    // Traverse the given array, p[]
    for (let i = 1; i <= n; i++) {
 
        // If current number is already
        // present at the right position
        if (p[i] == i) {
            continue;
        }
 
        // Store the current position of
        // the number 'i'
        let j = posOfCurrNum[i];
 
        // Case 1: If both the indices
        // satisfies the given condition
        if (Math.abs(i - j) * 2 >= n) {
 
            Swap(i, j, p, posOfCurrNum);
 
            ans.push([ i, j ]);
        }
 
        // Case 2: If the current number
        // 'i' is present at right side
        // of half of the given array
        else if (n / 2 <= i - 1) {
 
            Swap(1, i, p, posOfCurrNum);
            ans.push([ i, 1 ]);
 
            Swap(1, j, p, posOfCurrNum);
            ans.push([ 1, j ]);
 
            Swap(i, 1, p, posOfCurrNum);
            ans.push([ i, 1 ]);
        }
 
        // Case 3: If the position of the
        // current number 'i' is left side
        // of half of the given array
        else if (n - j >= n / 2) {
 
            Swap(i, n, p, posOfCurrNum);
            ans.push([ i, n ]);
 
            Swap(j, n, p, posOfCurrNum);
            ans.push([ j, n ]);
 
            Swap(i, n, p, posOfCurrNum);
            ans.push([ i, n ]);
        }
 
        // Case 4: For all other cases
        else {
            Swap(i, n, p, posOfCurrNum);
            ans.push([ i, n ]);
 
            Swap(n, 1, p, posOfCurrNum);
            ans.push([ n, 1 ]);
 
            Swap(1, j, p, posOfCurrNum);
            ans.push([ 1, j ]);
 
            Swap(1, n, p, posOfCurrNum);
            ans.push([ 1, n ]);
 
            Swap(i, n, p, posOfCurrNum);
            ans.push([ i, n ]);
        }
    }
 
    // Print the number of operations
    document.write(ans.length + '<br>');
 
    // Print the steps
    for (let p of ans)
        document.write(p[0] + " " + p[1] + '<br>');
}
 
// Driver Code
 
    // Given Input
    let n = 6;
 
    // Append 0 to consider
    // 1-based indexing
    let p = [ 0, 2, 5, 3, 1, 4, 6 ];
 
    // Function Call
    sortArray(p, n);
     
    // This code is contributed by gfgking.
</script>


Output: 

9
1 4
2 6
6 1
1 4
1 6
2 6
4 1
1 5
4 1

 

Time Complexity: O(N)
Auxiliary Space: O(N)

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads