给定一个大小为N的数组 arr[]由范围 [0, N-1] 中的唯一元素组成,任务是找到K ,这是通过选择三个不同的元素并重新排列它们来对给定数组进行排序所需的步骤数.此外,在 K 行中打印在这 K 个步骤中选择的索引。
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.
例子:
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.
方法:思路是先统计没有排序的元素,然后插入到一个无序集合中。如果 count 为 0,那么我们不需要任何数量的步骤来对数组进行排序,因此我们打印 0 并退出。否则,我们首先从集合中擦除 i = A[A[i]] 的所有元素,然后执行以下操作,直到集合变为空:
- 我们选择所有可能的索引组合(如果可用),以便对最少两个元素进行排序。
- 现在,如果 i = A[i],则更改元素的顺序并将它们从集合中删除。
- 然后,我们只剩下那些满足 i = A[A[i]] 并且这些元素的计数必须是 4 的倍数的元素,否则无法对元素进行排序。
- 然后,我们选择任意两对并执行两次更改元素的顺序。然后所有四个选定的元素都将被排序。
- 我们将所有涉及元素顺序变化的索引存储在一个向量中,并将其打印为答案。
让我们通过一个例子来理解上述方法。让数组 arr[] = {0, 8, 9, 10, 1, 7, 12, 4, 3, 2, 6, 5, 11}。然后:
- 最初,该集合将包含所有 12 个元素,并且没有满足 i = A[A[i]] 的元素。
- 现在,选择 {11, 5, 7} 并更改元素的顺序。然后,arr[] = {0, 8, 9, 10, 1, 5, 12, 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, 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 是数组的大小。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live