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++ 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 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 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# 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. |
<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> |
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)