Skip to content
Related Articles

Related Articles

Improve Article
Sort a permutation of first N Natural Numbers by swapping pairs satisfying given conditions
  • Last Updated : 22 Jun, 2021

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 postion 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 postion 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 postion 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

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 postion 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)

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes




My Personal Notes arrow_drop_up
Recommended Articles
Page :