📌  相关文章
📜  通过更改每个步骤中三个元素的顺序对数组进行排序的步骤数

📅  最后修改于: 2021-05-06 21:21:05             🧑  作者: Mango

给定大小为N的数组arr [] ,该数组包含范围为[0,N-1]的唯一元素,任务是找到K ,这是通过选择三个不同的元素并重新排列它们来对给定数组进行排序所需的步骤数。并且,在K行中打印在那K个步骤中选择的索引。

例子:

方法:想法是首先计算未排序的元素,然后将它们插入无序集合中。如果count为0,那么我们不需要对数组进行排序的任何步骤,因此我们输出0并退出。否则,我们首先擦除集合中i = A [A [i]]的所有元素,然后执行以下操作,直到集合为空:

  • 我们选择所有可能的索引组合(如果有),以使至少两个元素得到排序。
  • 现在,如果i = A [i],则更改元素的顺序并将其从集合中删除。
  • 然后,只剩下那些元素,使得i = A [A [i]],并且这些元素的计数必须是4的倍数,否则无法对元素进行排序。
  • 然后,我们选择任意两对,并执行两次更改元素的顺序。然后,所有四个选择的元素将被排序。
  • 我们将与元素顺序更改有关的所有索引存储在向量中,并将其打印为答案。

让我们通过一个例子来理解上述方法。令数组arr [] = {0,8,9,10,1,7,12,4,4,3,2,6,5,11}。然后:

  • 最初,该集合将包含所有12个元素,并且不存在i = A [A [i]]的元素。
  • 现在,选择{11,5,7}并更改元素的顺序。然后,arr [] = {0,8,9,10,1,5,12,7,7,3,2,6,4,11}。
  • 现在,选择{11,4,1}并更改元素的顺序。然后,arr [] = {0、1、9、10、4、5、12、7、3、2、6、8、11}。
  • 现在,选择{11,8,3}并更改元素的顺序。然后,arr [] = {0,1,9,3,4,5,12,7,8,2,2,6,10,11}。
  • 现在,选择{11,10,6}并更改元素的顺序。然后,arr [] = {0、1、9、3、4、5、6、7、8、2、10、12、11}。
  • 完成上述步骤后,剩下两对未排序的元素,使得i = A [A [i]]。
  • 最后,选择{2,11,9}和{11,9,5}并重新排序。然后,将arr [] = {0、1、2、3、4、5、6、7、8、9、10、11、12}进行排序。

下面是上述方法的实现:

// C++ program to sort the array
// by changing the order of
// three elements
  
#include 
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& 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& 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 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 > ans;
  
        // Temporary vector to store
        // the indices
        vector 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 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;
}
输出:
6
11 5 7
11 4 1
11 8 3
11 10 6
2 11 9
11 9 12

时间复杂度: O(N) ,其中N是数组的大小。