Sort from 0 to n - 1#8636

Sort from 0 to n - 1 (Editorial)

Consider the given sequence as a permutation of numbers from to n - 1. Represent it as a decomposition into disjoint cycles.

Each cycle can be sorted independently of the others. Let the length of a cycle be . Then, to place all elements of this cycle into their correct positions, it is sufficient to perform k - 1 swaps. Indeed, within a cycle, exactly one element can be immediately placed in its correct position, after which a cycle of length k - 1 remains, and the process continues in the same way.

Now iterate over all indices from to n - 1. If a_i = i, then the element is already in its correct position and nothing needs to be done. Otherwise, if a_i \ne i, it means we have found a cycle that has not yet been processed.

Next, we'll "unroll" this cycle. While a_i \ne i, swap the elements at positions and a_i. After such a swap, the element a_i moves to its correct position. By repeating this operation, we fix all elements of the current cycle.

Thus, to find the minimum number of swaps, it is sufficient to:

Example

Consider the second example. The permutation (4, 0, 3, 2, 1) decomposes into two cycles:

The first cycle requires 3 - 1 = 2 swaps, and the second requires 2 - 1 = 1 swap. Thus, the total minimum number of swaps is 2 + 1 = 3.

Algorithm implementation

Store the input permutation in the array . The performed swaps are stored in the array .

vector<int> a;
vector<pair<int, int> > ans;

Read the input permutation.

scanf("%d", &n);
a.resize(n);
for (i = 0; i < n; i++)
  scanf("%d", &a[i]);

If a_i \ne i, then process the cycle to which the element a_i belongs by performing the necessary swaps. The number of performed swaps is counted in the variable .

for (i = 0; i < n; i++)
  while (a[i] != i)
  {
    ans.push_back(make_pair(i, a[i]));
    swap(a[i], a[a[i]]);
    cnt++;
  }

Print the number of swaps , and then the swaps themselves.

printf("%d\n", cnt);
for (i = 0; i < ans.size(); i++)
  printf("%d %d\n", ans[i].first, ans[i].second);