Number of steps to sort the array by changing order of three elements in each step

Given an array arr[] of size N consisting of unique elements in the range [0, N-1], the task is to find K which is the number of steps required to sort the given array by selecting three distinct elements and rearranging them. And also, print the indices selected in those K steps in K lines.
For example, in the array {5, 4, 3, 2, 1, 0}, one possible way to sort the given array by selecting three distinct elements is to select the numbers {2, 1, 0} and sort them as {0, 1, 2} thereby making the array {5, 4, 3, 0, 1, 2}. Similarly, the remaining operations are performed and the indices selected ({3, 4, 5} in the above case) are printed in separate lines.
Examples:
Input: arr[] = {0, 5, 4, 3, 2, 1}
Output:
2
1 2 5
2 5 4
Explanation:
The above array can be sorted in 2 steps:
Step I: We change the order of elements at indices 1, 2, 5 then the array becomes {0, 1, 5, 3, 2, 4}.
Step II: We again change the order of elements at the indices 2, 5, 4 then the array becomes {0, 1, 2, 3, 4, 5} which is sorted.
Input: arr[] = {0, 3, 1, 6, 5, 2, 4}
Output: -1
Explanation:
The above array cannot be sorted in any number of steps.
Suppose we choose indices 1, 3, 2 then the array becomes {0, 1, 6, 3, 5, 2, 4}
After that, we choose indices 2, 6, 4 then the array becomes {0, 1, 5, 3, 4, 2, 6}.
Now only two elements are left unsorted so we cannot choose 3 elements so the above array cannot be sorted. We can try with any order of indices and we will always be left with 2 elements unsorted.
Approach: The idea is to first count the elements which are not sorted and insert them in an unordered set. If count is 0 then we don’t need any number of steps for sorting the array so we print 0 and exit. Else, we first erase all the elements from the set for which i = A[A[i]] then we perform the following operation till the set becomes empty:
- We select all the possible combination of indices(if available) such that minimum two elements will get sorted.
- Now, change the order of the elements and erase them from the set if i = A[i].
- Then, we are left with only those elements such that i = A[A[i]] and the count of those must be a multiple of 4 otherwise it is not possible to sort the elements.
- Then, we choose any two pair and perform changing the order of elements two times. Then all the four chosen elements will get sorted.
- We store all the indices which are involved in the changing of orders of elements in a vector and print it as the answer.
Let’s understand the above approach with an example. Let the array arr[] = {0, 8, 9, 10, 1, 7, 12, 4, 3, 2, 6, 5, 11}. Then:
- Initially, the set will contain all the 12 elements and there are no elements such that i = A[A[i]].
- Now, {11, 5, 7} are chosen and the order of the elements are changed. Then, arr[] = {0, 8, 9, 10, 1, 5, 12, 7, 3, 2, 6, 4, 11}.
- Now, {11, 4, 1} are chosen and the order of the elements are changed. Then, arr[] = {0, 1, 9, 10, 4, 5, 12, 7, 3, 2, 6, 8, 11}.
- Now, {11, 8, 3} are chosen and the order of the elements are changed. Then, arr[] = {0, 1, 9, 3, 4, 5, 12, 7, 8, 2, 6, 10, 11}.
- Now, {11, 10, 6} are chosen and the order of the elements are changed. Then, arr[] = {0, 1, 9, 3, 4, 5, 6, 7, 8, 2, 10, 12, 11}.
- After the above step, we are left with two pairs of unsorted elements such that i = A[A[i]].
- Finally, {2, 11, 9} and {11, 9, 5} are chosen and reordered. Then, arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} which is sorted.
Below is the implementation of the above approach:
CPP
// C++ program to sort the array// by changing the order of// three elements#include <bits/stdc++.h>using namespace std;// Function to change the order of// the elements having a temporary// vector and the required indices// as the argumentsvoid cngorder(vector<int>& v, int i, int j, int k){ int temp = v[k]; v[k] = v[j]; v[j] = v[i]; v[i] = temp;}// Function to sort the elements having// the given array and its size.void sortbyorder3(vector<int>& A, int n){ // Flag to check whether the sorting // is possible or not bool flag = 0; int count = 0; // Set that will contains unsorted // elements unordered_set<int> s; // Iterating through the elements for (int i = 0; i < n; i++) { // Inserting the required elements // in the set if (i != A[i]) count++, s.insert(i); } // When the given array is // already sorted if (count == 0) cout << "0" << endl; else { // Vector that will contain // the answer vector<vector<int> > ans; // Temporary vector to store // the indices vector<int> vv; int x, y, z; count = 0; // Loop that will execute till the // set becomes empty while (!s.empty()) { auto it = s.begin(); int i = *it; // Check for the condition if (i == A[A[i]]) { s.erase(i); s.erase(A[i]); continue; } // Case when the minimum two // elements will get sorted else { x = A[i], y = A[A[i]], z = A[A[A[i]]]; vv.push_back(x), vv.push_back(y), vv.push_back(z); // Changing the order of elements cngorder(A, x, y, z); // Pushing the indices to the // answer vector ans.push_back(vv); // If the third element also // gets sorted if (vv[0] == A[vv[0]]) s.erase(vv[0]); // Erasing the two sorted elements // from the set s.erase(vv[1]), s.erase(vv[2]); vv.clear(); } } count = 0; // The count of the remaining // unsorted elements for (int i = 0; i < n; i++) { if (i != A[i]) count++; } // If the count of the left // unsorted elements is not // a multiple of 4, then // sorting is not possible if (count % 4 != 0) flag = 1; // Only the elements such that // i = A[A[i]] are left // for sorting else { // Indices of any one element // from the two pairs that // will be sorted in 2 steps int i1 = -1, i2 = -1; for (int i = 0; i < n; i++) { // Index of any element of // the pair if (A[i] != i && i1 == -1) { i1 = i; } // When we find the second // pair and the index of // any one element is stored else if (A[i] != i && i1 != -1 && i2 == -1) { if (i1 == A[i]) continue; else i2 = i; } // When we got both the pair // of elements if (i1 != -1 && i2 != -1) { // Remaining two indices // of the elements int i3 = A[i1], i4 = A[i2]; // The first order of indices vv.push_back(i1), vv.push_back(i2), vv.push_back(A[i1]); // Pushing the indices to the // answer vector ans.push_back(vv); vv.clear(); // The second order of indices vv.push_back(i2), vv.push_back(A[i1]), vv.push_back(A[i2]); // Pushing the indices to the // answer vector ans.push_back(vv); vv.clear(); // Changing the order of the // first combination of // the indices cngorder(A, i1, i2, i3); // Changing the order of the // second combination of // the indices after which all // the 4 elements will be sorted cngorder(A, i2, i3, i4); i1 = -1, i2 = -1; } } } // If the flag value is 1 // the sorting is not possible if (flag == 1) cout << "-1" << endl; else { // Printing the required number // of steps cout << ans.size() << endl; // Printing the indices involved // in the shifting for (int i = 0; i < ans.size(); i++) { cout << ans[i][0] << " " << ans[i][1] << " " << ans[i][2] << endl; } } }}// Driver codeint main(){ int n; vector<int> A{ 0, 8, 9, 10, 1, 7, 12, 4, 3, 2, 6, 5, 11 }; n = A.size(); // Calling the sorting function sortbyorder3(A, n); return 0;} |
Java
// java program to sort the array// by changing the order of// three elementsimport java.util.*;class Main { // Function to change the order of // the elements having a temporary // vector and the required indices // as the arguments static void cngorder(List<Integer> v, int i, int j, int k) { int temp = v.get(k); v.set(k, v.get(j)); v.set(j, v.get(i)); v.set(i, temp); } // Function to sort the elements having // the given array and its size. static void sortbyorder3(List<Integer> A, int n) { // Flag to check whether the sorting // is possible or not boolean flag = false; int count = 0; // Set that will contains unsorted // elements HashSet<Integer> s = new HashSet<>(); // Iterating through the elements for (int i = 0; i < n; i++) { // Inserting the required elements // in the set if (i != A.get(i)) { count++; s.add(i); } } // When the given array is // already sorted if (count == 0) { System.out.println("0"); } else { // Vector that will contain // the answer List<List<Integer>> ans = new ArrayList<>(); // Temporary vector to store // the indices List<Integer> vv = new ArrayList<>(); int x, y, z; count = 0; // Loop that will execute till the // set becomes empty while (!s.isEmpty()) { Iterator<Integer> it = s.iterator(); // Check for the condition int i = it.next(); if (i == A.get(A.get(i))) { s.remove(i); s.remove(A.get(i)); continue; } // Case when the minimum two else { x = A.get(i); y = A.get(A.get(i)); z = A.get(A.get(A.get(i))); vv.add(x); vv.add(y); vv.add(z); // Changing the order of elements cngorder(A, x, y, z); // Pushing the indices to the // answer vector ans.add(new ArrayList<>(vv)); // If the third element also // gets sorted if (vv.get(0).equals(A.get(vv.get(0)))){ s.remove(vv.get(0)); } // Erasing the two sorted elements // from the set s.remove(vv.get(1)); s.remove(vv.get(2)); vv.clear(); } } count = 0; // The count of the remaining // unsorted elements for (int i = 0; i < n; i++) { if (i != A.get(i)) { count++; } } // If the count of the left // unsorted elements is not // a multiple of 4, then // sorting is not possible if (count % 4 != 0) { flag = true; } // Only the elements such that // i = A[A[i]] are left // for sorting else { // Indices of any one element // from the two pairs that // will be sorted in 2 steps int i1 = -1, i2 = -1; for (int i = 0; i < n; i++) { // Index of any element of // the pair if (!A.get(i).equals(i) && i1 == -1) { i1 = i; } // When we find the second // pair and the index of // any one element is stored else if (!A.get(i).equals(i) && i1 != -1 && i2 == -1) { if (i1 == A.get(i)) continue; else i2 = i; } if (i1 != -1 && i2 != -1) { // Remaining two indices // of the elements int i3 = A.get(i1), i4 = A.get(i2); // The first order of indices vv.add(i1); vv.add(i2); vv.add(A.get(i1)); // Pushing the indices to the // answer vector ans.add(new ArrayList<>(vv)); vv.clear(); // The second order of indices vv.add(i2); vv.add(A.get(i1)); vv.add(A.get(i2)); // Pushing the indices to the // answer vector ans.add(new ArrayList<>(vv)); vv.clear(); // Changing the order of the // first combination of // the indices cngorder(A, i1, i2, i3); // Changing the order of the // second combination of // the indices after which all // the 4 elements will be sorted cngorder(A, i2, i3, i4); i1 = -1; i2 = -1; } } } // If the flag value is 1 // the sorting is not possible if (flag) { System.out.println("-1"); } else { // Printing the required number // of steps System.out.println(ans.size()); // Printing the indices involved // in the shifting for (int i = 0; i < ans.size(); i++) { System.out.println(ans.get(i).get(0) + " " + ans.get(i).get(1) + " " + ans.get(i).get(2)); } } } } // Driver code public static void main(String[] args) { List<Integer> A = new ArrayList<>(Arrays.asList(0, 8, 9, 10, 1, 7, 12, 4, 3, 2, 6, 5, 11)); int n = A.size(); sortbyorder3(A, n); }}//This code is contributed by shivregkec |
C#
// C# program to sort the array// by changing the order of// three elementsusing System;using System.Collections.Generic;class GFG { // Function to change the order of // the elements having a temporary // vector and the required indices // as the arguments static void cngorder(List<int> v, int i, int j, int k) { int temp = v[k]; v[k] = v[j]; v[j] = v[i]; v[i] = temp; } // Function to sort the elements having // the given array and its size. static void sortbyorder3(List<int> A, int n) { // Flag to check whether the sorting // is possible or not bool flag = false; int count = 0; // Set that will contains unsorted // elements HashSet<int> s = new HashSet<int>(); // Iterating through the elements for (int i = 0; i < n; i++) { // Inserting the required elements // in the set if (i != A[i]) { count++; s.Add(i); } } // When the given array is // already sorted if (count == 0) { Console.WriteLine("0"); } else { // Vector that will contain // the answer List<List<int>> ans = new List<List<int>>(); // Temporary vector to store // the indices List<int> vv = new List<int>(); int x, y, z; count = 0; // Loop that will execute till the // set becomes empty while (s.Count > 0) { var it = s.GetEnumerator(); it.MoveNext(); // Check for the condition int i = it.Current; if (i == A[A[i]]) { s.Remove(i); s.Remove(A[i]); continue; } // Case when the minimum two else { x = A[i]; y = A[A[i]]; z = A[A[A[i]]]; vv.Add(x); vv.Add(y); vv.Add(z); // Changing the order of elements cngorder(A, x, y, z); // Pushing the indices to the // answer vector ans.Add(new List<int>(vv)); // If the third element also // gets sorted if (vv[0] == A[vv[0]]) { s.Remove(vv[0]); } // Erasing the two sorted elements // from the set s.Remove(vv[1]); s.Remove(vv[2]); vv.Clear(); } } count = 0; // The count of the remaining // unsorted elements for (int i = 0; i < n; i++) { if (i != A[i]) { count++; } } // If the count of the left // unsorted elements is not // a multiple of 4, then // sorting is not possible if (count % 4 != 0) { flag = true; } // Only the elements such that // i = A[A[i]] are left // for sorting else { // Indices of any one element // from the two pairs that // will be sorted in 2 steps int i1 = -1, i2 = -1; for (int i = 0; i < n; i++) { // Index of any element of // the pair if (A[i] != i && i1 == -1) { i1 = i; } // When we find the second // pair and the index of // any one element is stored else if (A[i] != i && i1 != -1 && i2 == -1) { if (i1 == A[i]) continue; else i2 = i; } if (i1 != -1 && i2 != -1) { // Remaining two indices // of the elements int i3 = A[i1], i4 = A[i2]; // The first order of indices vv.Add(i1); vv.Add(i2); vv.Add(A[i1]); // Pushing the indices to the // answer vector ans.Add(new List<int>(vv)); vv.Clear(); // The second order of indices vv.Add(i2); vv.Add(A[i1]); vv.Add(A[i2]); // Pushing the indices to the // answer vector ans.Add(new List<int>(vv)); vv.Clear(); // Changing the order of the // first combination of // the indices cngorder(A, i1, i2, i3); // Changing the order of the // second combination of // the indices after which all // the 4 elements will be sorted cngorder(A, i2, i3, i4); i1 = -1; i2 = -1; } } } // If the flag value is 1 // the sorting is not possible if (flag) { Console.WriteLine("-1"); } else { // Printing the required number // of steps Console.WriteLine(ans.Count); // Printing the indices involved // in the shifting for (int i = 0; i < ans.Count; i++) { Console.WriteLine(ans[i][0] + " " + ans[i][1] + " " + ans[i][2]); } } } } // Driver code static void Main(string[] args) { List<int> A = new List<int> { 0, 8, 9, 10, 1, 7, 12, 4, 3, 2, 6, 5, 11 }; int n = A.Count; sortbyorder3(A, n); }}//This code is contributed by Shivhack999 |
6 11 5 7 11 4 1 11 8 3 11 10 6 2 11 9 11 9 12
Time Complexity: O(N), where N is the size of the array.
Auxiliary space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



