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!



