Count operations to sort given Permutation Array in increasing order
Last Updated :
07 Dec, 2023
Given an unsorted permutation array of size N and an integer K ( 1 ≤ K ≤ N ), the task is to sort this permutation array in increasing order in the minimum number of steps, where in each step K elements have to be removed from the array and inserted at the front in increasing order and remaining elements should be in arbitrary order.
Examples:
Input: N = 5, P[] = [ 2, 4, 1, 5, 3 ], K = 2
Output: 2
Explanation: Following are the operations that can be performed to sort the permutation in increasing order.
- Operation1: Choose elements 3, 4 remove them from P then sort them in increasing order – 4, 3 and finally add them in front of P, So, P becomes [3, 4, 2, 1, 5].
- Operation 2: Choose elements 1, 2 remove them from P then sort them in increasing order – 1, 2 and finally add them in front of P, So P becomes [1, 2, 3, 4, 5}.
So the minimum number of operations required to sort the permutation P in increasing order is 2.
Input : N = 3, P[] = [3, 1, 2], K = 1
Output: 2
Explanation: Following are the operations that can be performed to sort the permutation in increasing order.
- Operation 1: Choose element 2 remove it from P then sort it in increasing order – 2 and finally add it in front of P, So P becomes [2, 3, 1].
- Operation 2: Choose element 3 remove it from P then sort it in increasing order – 1 and finally add it in front of P, So P becomes [ 1, 2, 3 ].
So the minimum number of operations required to sort the permutation P in increasing order is 2.
Approach: This can be solved by the following idea:
Suppose x elements do not participate in any operation means they are already sorted in increasing order. And since this x must be maximized to minimize the number of operations, we need to find the maximal subsequence of the numbers […2, 1]. Let this sequence have w numbers, then the answer is ceil((n − w) / k).
Follow the steps to solve the problem:
- Initialize correct_pos with 0.
- Initialize counter with 0.
- Run a loop from i: N-1 to 0 and check:
- If ( P[i] == counter ) then increment correct_pos with 1 and counter with 1.
- Calculate the Number of wrong_pos elements by ( N – correct_pos ).
- Calculate minimum number operation by taking ceil of ( wrong_pos / K ).
- Return the minimum number of operations.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int min_operation_to_sort( int N, vector< int >& P, int K)
{
int correct_pos = 0;
int counter = 1;
for ( int i = N - 1; i >= 0; i--) {
if (P[i] == counter) {
correct_pos++;
counter++;
}
}
int wrong_pos = N - correct_pos;
int min_operation = (wrong_pos + K - 1) / K;
return min_operation;
}
int main()
{
int N = 5;
vector< int > P = { 2, 4, 1, 5, 3 };
int K = 2;
cout << min_operation_to_sort(N, P, K);
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int minOperationToSort( int N, List<Integer> P, int K) {
int correct_pos = 0 ;
int counter = 1 ;
for ( int i = N - 1 ; i >= 0 ; i--) {
if (P.get(i) == counter) {
correct_pos++;
counter++;
}
}
int wrong_pos = N - correct_pos;
int min_operation = (wrong_pos + K - 1 ) / K;
return min_operation;
}
public static void main(String[] args) {
int N = 5 ;
List<Integer> P = new ArrayList<>(Arrays.asList( 2 , 4 , 1 , 5 , 3 ));
int K = 2 ;
System.out.println(minOperationToSort(N, P, K));
}
}
|
Python3
def min_operation_to_sort(N, P, K):
correct_pos = 0
counter = 1
for i in range (N - 1 , - 1 , - 1 ):
if P[i] = = counter:
correct_pos + = 1
counter + = 1
wrong_pos = N - correct_pos
min_operation = (wrong_pos + K - 1 ) / / K
return min_operation
N = 5
P = [ 2 , 4 , 1 , 5 , 3 ]
K = 2
print (min_operation_to_sort(N, P, K))
|
C#
using System;
using System.Collections.Generic;
class Program {
static int min_operation_to_sort( int N, List< int > P, int K) {
int correct_pos = 0;
int counter = 1;
for ( int i = N - 1; i >= 0; i--) {
if (P[i] == counter) {
correct_pos++;
counter++;
}
}
int wrong_pos = N - correct_pos;
int min_operation = (wrong_pos + K - 1) / K;
return min_operation;
}
static void Main( string [] args) {
int N = 5;
List< int > P = new List< int >() { 2, 4, 1, 5, 3 };
int K = 2;
Console.WriteLine(min_operation_to_sort(N, P, K));
}
}
|
Javascript
function min_operation_to_sort(N, P, K) {
let correct_pos = 0;
let counter = 1;
for (let i = N - 1; i >= 0; i--) {
if (P[i] == counter) {
correct_pos++;
counter++;
}
}
let wrong_pos = N - correct_pos;
let min_operation = Math.ceil(wrong_pos / K);
return min_operation;
}
let N = 5;
let P = [2, 4, 1, 5, 3];
let K = 2;
console.log(min_operation_to_sort(N, P, K));
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Another Approach:
By using the cycle: A cycle in a permutation is a sequence of elements that can be cyclically permuted, which means that the elements can be shifted to the right or left within the sequence without changing the order of the elements. For example, the permutation [3, 1, 4, 2] has two cycles: [3, 4, 2, 1] and [1].
This can sort the permutation by performing a series of cyclic permutations, where each cyclic permutation involves only elements that belong to the same cycle. In each cycle, sort the elements by performing a series of swaps. The number of swaps required to sort a cycle is equal to the length of the cycle minus one.
Follow the steps to solve the problem:
- Initialize a list of visited elements to all False.
- Initialize a variable for the number of operations to zero.
- For each element in the permutation, if the element has not been visited, then:
a. Start a new cycle with this element.
b. While the cycle has not returned to the starting element:
i. Mark the current element as visited.
ii. Move to the next element in the cycle.
iii. If the next element has not been visited, add it to the cycle.
c. Sort the cycle by performing a series of swaps, and increment the number of operations by the number of swaps.
- Return the number of operations.
Below is the implementation of the above approach:
C++
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
int find_min_operations( int N, vector< int >& P, int K)
{
vector< bool > visited(N, false );
int num_ops = 0;
for ( int i = 0; i < N; i++) {
if (!visited[i]) {
int cycle_start = i;
int cycle_length = 0;
while (!visited[cycle_start]) {
visited[cycle_start] = true ;
cycle_start = P[cycle_start] - 1;
cycle_length++;
}
num_ops += ceil (( double )(cycle_length - 1) / K);
}
}
return num_ops;
}
int main()
{
int N = 5, K = 2;
vector< int > P = { 2, 4, 1, 5, 3 };
int min_ops = find_min_operations(N, P, K);
cout << "Minimum number of operations: " << min_ops
<< endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int
findMinOperations( int N, List<Integer> P, int K)
{
boolean [] visited = new boolean [N];
int numOps = 0 ;
for ( int i = 0 ; i < N; i++) {
if (!visited[i]) {
int cycleStart = i;
int cycleLength = 0 ;
while (!visited[cycleStart]) {
visited[cycleStart] = true ;
cycleStart = P.get(cycleStart) - 1 ;
cycleLength++;
}
numOps += Math.ceil(
( double )(cycleLength - 1 ) / K);
}
}
return numOps;
}
public static void main(String[] args)
{
int N = 5 , K = 2 ;
List<Integer> P = Arrays.asList( 2 , 4 , 1 , 5 , 3 );
int minOps = findMinOperations(N, P, K);
System.out.println( "Minimum number of operations: "
+ minOps);
}
}
|
Python3
import math
def find_min_operations(N, P, K):
visited = [ False ] * N
num_ops = 0
for i in range (N):
if not visited[i]:
cycle_start = i
cycle_length = 0
while not visited[cycle_start]:
visited[cycle_start] = True
cycle_start = P[cycle_start] - 1
cycle_length + = 1
num_ops + = math.ceil((cycle_length - 1 ) / K)
return num_ops
N = 5
K = 2
P = [ 2 , 4 , 1 , 5 , 3 ]
min_ops = find_min_operations(N, P, K)
print ( "Minimum number of operations:" , min_ops)
|
C#
using System;
class Program
{
static void Main()
{
int N = 5;
int K = 2;
int [] P = { 2, 4, 1, 5, 3 };
int minOps = FindMinOperations(N, P, K);
Console.WriteLine( "Minimum number of operations: " + minOps);
}
static int FindMinOperations( int N, int [] P, int K)
{
bool [] visited = new bool [N];
int numOps = 0;
for ( int i = 0; i < N; i++)
{
if (!visited[i])
{
int cycleStart = i;
int cycleLength = 0;
while (!visited[cycleStart])
{
visited[cycleStart] = true ;
cycleStart = P[cycleStart] - 1;
cycleLength += 1;
}
numOps += ( int )Math.Ceiling((cycleLength - 1) / ( double )K);
}
}
return numOps;
}
}
|
Javascript
function find_min_operations(N, P, K) {
var visited = new Array(N).fill( false );
var num_ops = 0;
for ( var i = 0; i < N; i++) {
if (!visited[i]) {
cycle_start = i;
cycle_length = 0;
while (!visited[cycle_start]) {
visited[cycle_start] = true ;
cycle_start = P[cycle_start] - 1;
cycle_length++;
}
num_ops += Math.ceil((cycle_length - 1) / K);
}
}
return num_ops;
}
var N = 5;
var K = 2;
var P = [2, 4, 1, 5, 3];
var min_ops = find_min_operations(N, P, K);
console.log( "Minimum number of operations:" , min_ops);
|
Output
Minimum number of operations: 2
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...