# 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[1] = P[P[P[1]]] = P[P[2]] = P[3] = 1
P[2] = P[P[P[2]]] = P[P[3]] = P[1] = 2
P[3] = P[P[P[3]]] = P[P[1]] = P[2] = 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++ 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[0])) - 1; ` ` `  `    ``// Calling function ` `    ``cout << minimumOperations(P, n); ` ` `  `    ``return` `0; ` `} `

 `// 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 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# 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 `

 ` `

Output:
```2
```

Time Complexity : O(N*LogN)

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.

Article Tags :