Wednesday, November 20, 2024
Google search engine
HomeData Modelling & AINumber of steps to sort the array by changing order of three...

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: 

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 arguments
void 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 code
int 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 elements
import 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 elements
using 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


Output: 

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)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments