# Minimum number of given operations required to convert a permutation into an identity permutation

Given a permutation P (P1, P2, P3, … Pn) of first n natural numbers. Find the minimum number of operations to convert it into an identity permutation i.e. 1, 2, 3, …, n where each operation is defined as:
P[i] = P[P[P[i]]] i from 1 to n (1 based indexing). If there is no way to convert then print -1.

Examples:

Input: arr[] = {2, 3, 1}
Output: 1
After 1 operation:
P = P[P[P]] = P[P] = P = 1
P = P[P[P]] = P[P] = P = 2
P = P[P[P]] = P[P] = P = 3
Thus after 1 operation we obtain an identity permutation.

Input: arr[] = {2, 1, 3}
Output: -1
There is no way to obtain identity permutation
no matter how many operations we apply.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: First, find all the cycles in the given permutation. Here, a cycle is a directed graph in which there is an edge from an element e to the element on position e.
For example, Here’s the graph for permutation {4, 6, 5, 3, 2, 1, 8, 7} Now in one operation, each cycle of length 3k breaks into 3 cycles each of length k while cycles of length 3k+1 or 3k+2 do not break. Since in the end, we need all cycles of length 1, therefore, all cycles must be a power of 3 otherwise answer doesn’t exist. The answer would then be the maximum of log(base 3) of all cycle lengths.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach ` `#include ` `using` `namespace` `std; ` ` `  `int` `calculateCycleOperations(``int` `len) ` `{ ` `    ``int` `cycle_operations = 0; ` `    ``while` `(len) { ` `        ``len /= 3; ` `        ``++cycle_operations; ` `    ``} ` `    ``return` `--cycle_operations; ` `} ` ` `  `// Function to return the minimum operations required ` `int` `minimumOperations(``int` `p[], ``int` `n) ` `{ ` ` `  `    ``// Array to keep track of visited elements ` `    ``bool` `visited[n + 1] = { 0 }; ` ` `  `    ``// To store the final answer ` `    ``int` `ans = 0; ` ` `  `    ``// Looping through all the elements ` `    ``for` `(``int` `i = 1; i <= n; i++) { ` ` `  `        ``// Current element ` `        ``int` `ele = p[i]; ` ` `  `        ``// If current element is not present in the ` `        ``// previous cycles then only consider this ` `        ``if` `(!visited[ele]) { ` ` `  `            ``// Mark current element visited so that it ` `            ``// will not be considered in other cycles ` `            ``visited[ele] = 1; ` ` `  `            ``// To store the length of each cycle ` `            ``int` `len = 1; ` `            ``ele = p[ele]; ` ` `  `            ``// Calculating cycle length ` `            ``while` `(!visited[ele]) { ` `                ``visited[ele] = 1; ` `                ``++len; ` `                ``ele = p[ele]; ` `            ``} ` ` `  `            ``// Operations needed for this cycle to reduce ` `            ``// to length 1 (if possible) ` `            ``int` `operations = calculateCycleOperations(len); ` ` `  `            ``// Checking cycle length to be power of 3 ` `            ``// if not, then return -1 ` `            ``int` `num = ``pow``(3, operations); ` `            ``if` `(num != len) { ` `                ``return` `-1; ` `            ``} ` ` `  `            ``// Taking maximum of the operations ` `            ``ans = max(ans, operations); ` `        ``} ` `    ``} ` `    ``return` `ans; ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``// 1-based indexing ` `    ``int` `P[] = { -1, 4, 6, 5, 3, 2, 7, 8, 9, 1 }; ` `    ``int` `n = (``sizeof``(P) / ``sizeof``(P)) - 1; ` ` `  `    ``// Calling function ` `    ``cout << minimumOperations(P, n); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java implementation of the approach ` `import` `java.util.*; ` ` `  `class` `GFG ` `{ ` ` `  `static` `int` `calculateCycleOperations(``int` `len) ` `{ ` `    ``int` `cycle_operations = ``0``; ` `    ``while` `(len > ``0``)  ` `    ``{ ` `        ``len /= ``3``; ` `        ``++cycle_operations; ` `    ``} ` `    ``return` `--cycle_operations; ` `} ` ` `  `// Function to return the minimum operations required ` `static` `int` `minimumOperations(``int` `p[], ``int` `n) ` `{ ` ` `  `    ``// Array to keep track of visited elements ` `    ``int` `[]visited = ``new` `int``[n+``1``]; ` `    ``Arrays.fill(visited,``0``); ` ` `  `    ``// To store the final answer ` `    ``int` `ans = ``0``; ` ` `  `    ``// Looping through all the elements ` `    ``for` `(``int` `i = ``1``; i <= n; i++)  ` `    ``{ ` ` `  `        ``// Current element ` `        ``int` `ele = p[i]; ` ` `  `        ``// If current element is not present in the ` `        ``// previous cycles then only consider this ` `        ``if` `(visited[ele] == ``0``)  ` `        ``{ ` ` `  `            ``// Mark current element visited so that it ` `            ``// will not be considered in other cycles ` `            ``visited[ele] = ``1``; ` ` `  `            ``// To store the length of each cycle ` `            ``int` `len = ``1``; ` `            ``ele = p[ele]; ` ` `  `            ``// Calculating cycle length ` `            ``while` `(visited[ele] == ``0``) ` `            ``{ ` `                ``visited[ele] = ``1``; ` `                ``++len; ` `                ``ele = p[ele]; ` `            ``} ` ` `  `            ``// Operations needed for this cycle to reduce ` `            ``// to length 1 (if possible) ` `            ``int` `operations = calculateCycleOperations(len); ` ` `  `            ``// Checking cycle length to be power of 3 ` `            ``// if not, then return -1 ` `            ``int` `num = (``int``)Math.pow(``3``, operations); ` `            ``if` `(num != len) { ` `                ``return` `-``1``; ` `            ``} ` ` `  `            ``// Taking maximum of the operations ` `            ``ans = Math.max(ans, operations); ` `        ``} ` `    ``} ` `    ``return` `ans; ` `} ` ` `  `// Driver code ` `public` `static` `void` `main(String args[]) ` `{ ` `    ``// 1-based indexing ` `    ``int` `P[] = { -``1``, ``4``, ``6``, ``5``, ``3``, ``2``, ``7``, ``8``, ``9``, ``1` `}; ` `    ``int` `n = P.length-``1``; ` ` `  `    ``// Calling function ` `    ``System.out.println(minimumOperations(P, n)); ` `} ` `} ` ` `  `// This code is contributed by ` `// Surendra_Gangwar `

## Python3

 `# Python3 implementation of the approach ` `def` `calculateCycleOperations(length): ` ` `  `    ``cycle_operations ``=` `0` `    ``while` `length > ``0``:  ` `        ``length ``/``/``=` `3` `        ``cycle_operations ``+``=` `1` `     `  `    ``return` `cycle_operations ``-` `1` ` `  `# Function to return the minimum  ` `# operations required ` `def` `minimumOperations(p, n): ` ` `  `    ``# Array to keep track of visited elements ` `    ``visited ``=` `[``0``] ``*` `(n ``+` `1``)  ` ` `  `    ``# To store the final answer ` `    ``ans ``=` `0` ` `  `    ``# Looping through all the elements ` `    ``for` `i ``in` `range``(``1``, n ``+` `1``):  ` ` `  `        ``# Current element ` `        ``ele ``=` `p[i] ` ` `  `        ``# If current element is not present in the ` `        ``# previous cycles then only consider this ` `        ``if` `not` `visited[ele]:  ` ` `  `            ``# Mark current element visited so that it ` `            ``# will not be considered in other cycles ` `            ``visited[ele] ``=` `1` ` `  `            ``# To store the length of each cycle ` `            ``length ``=` `1` `            ``ele ``=` `p[ele] ` ` `  `            ``# Calculating cycle length ` `            ``while` `not` `visited[ele]:  ` `                ``visited[ele] ``=` `1` `                ``length ``+``=` `1` `                ``ele ``=` `p[ele] ` `             `  `            ``# Operations needed for this cycle to ` `            ``# reduce to length 1 (if possible) ` `            ``operations ``=` `calculateCycleOperations(length) ` ` `  `            ``# Checking cycle length to be power ` `            ``# of 3 if not, then return -1 ` `            ``num ``=` `pow``(``3``, operations) ` `            ``if` `num !``=` `length:  ` `                ``return` `-``1` ` `  `            ``# Taking maximum of the operations ` `            ``ans ``=` `max``(ans, operations) ` `         `  `    ``return` `ans ` ` `  `# Driver code ` `if` `__name__ ``=``=` `"__main__"``: ` ` `  `    ``# 1-based indexing ` `    ``P ``=` `[``-``1``, ``4``, ``6``, ``5``, ``3``, ``2``, ``7``, ``8``, ``9``, ``1``]  ` `    ``n ``=` `len``(P) ``-` `1` ` `  `    ``# Calling function ` `    ``print``(minimumOperations(P, n)) ` ` `  `# This code is contributed by Rituraj Jain `

## C#

 `// C# implementation of the above approach  ` `using` `System; ` ` `  `class` `GFG  ` `{  ` ` `  `    ``static` `int` `calculateCycleOperations(``int` `len)  ` `    ``{  ` `        ``int` `cycle_operations = 0;  ` `        ``while` `(len > 0)  ` `        ``{  ` `            ``len /= 3;  ` `            ``++cycle_operations;  ` `        ``}  ` `        ``return` `--cycle_operations;  ` `    ``}  ` `     `  `    ``// Function to return the minimum operations required  ` `    ``static` `int` `minimumOperations(``int` `[]p, ``int` `n)  ` `    ``{  ` `     `  `        ``// Array to keep track of visited elements  ` `        ``int` `[]visited = ``new` `int``[n+1];  ` ` `  `        ``// To store the final answer  ` `        ``int` `ans = 0;  ` `     `  `        ``// Looping through all the elements  ` `        ``for` `(``int` `i = 1; i <= n; i++)  ` `        ``{  ` `     `  `            ``// Current element  ` `            ``int` `ele = p[i];  ` `     `  `            ``// If current element is not present in the  ` `            ``// previous cycles then only consider this  ` `            ``if` `(visited[ele] == 0)  ` `            ``{  ` `     `  `                ``// Mark current element visited so that it  ` `                ``// will not be considered in other cycles  ` `                ``visited[ele] = 1;  ` `     `  `                ``// To store the length of each cycle  ` `                ``int` `len = 1;  ` `                ``ele = p[ele];  ` `     `  `                ``// Calculating cycle length  ` `                ``while` `(visited[ele] == 0)  ` `                ``{  ` `                    ``visited[ele] = 1;  ` `                    ``++len;  ` `                    ``ele = p[ele];  ` `                ``}  ` `     `  `                ``// Operations needed for this cycle to reduce  ` `                ``// to length 1 (if possible)  ` `                ``int` `operations = calculateCycleOperations(len);  ` `     `  `                ``// Checking cycle length to be power of 3  ` `                ``// if not, then return -1  ` `                ``int` `num = (``int``)Math.Pow(3, operations);  ` `                ``if` `(num != len)  ` `                ``{  ` `                    ``return` `-1;  ` `                ``}  ` `     `  `                ``// Taking maximum of the operations  ` `                ``ans = Math.Max(ans, operations);  ` `            ``}  ` `        ``}  ` `        ``return` `ans;  ` `    ``}  ` `     `  `    ``// Driver code  ` `    ``public` `static` `void` `Main()  ` `    ``{  ` `        ``// 1-based indexing  ` `        ``int` `[]P = { -1, 4, 6, 5, 3, 2, 7, 8, 9, 1 };  ` `        ``int` `n = P.Length-1;  ` `     `  `        ``// Calling function  ` `        ``Console.WriteLine(minimumOperations(P, n));  ` `    ``}  ` `}  ` ` `  `// This code is contributed by Ryuga `

## PHP

 ` `

Output:

```2
```

Time Complexity : O(N*LogN) My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.