Program to find minimum number of swaps needed to arrange all pair of socks together in C++


Suppose we have a list of numbers called row and this is representing socks lying in a row. They are not sorted, but we want to rearrange them so that each pair of socks are side by side like (0, 1), (2, 3), (4, 5), and so on. We have to find the minimum number of swaps required to rearrange them.

So, if the input is like row = [0, 5, 6, 2, 1, 3, 7, 4], then the output will be 2, as the row orders are

  • [0, 5, 6, 2, 1, 3, 7, 4]

  • [0, 1, 6, 2, 5, 3, 7, 4]

  • [0, 1, 3, 2, 5, 6, 7, 4]

  • [0, 1, 3, 2, 5, 4, 7, 6]

To solve this, we will follow these steps −

  • Define an array p and another array sz

  • Define a function find(), this will take u,

  • return (if p[u] is same as u, then u, otherwise find(p[u]) and p[u] := find(p[u]))

  • Define a function join(), this will take u, v,

  • pu := find((u), pv := find(v))

  • if pu is same as pv, then −

    • return

  • if sz[pu] >= sz[pv], then −

    • p[pv] := pu

    • sz[pu] := sz[pu] + sz[pv]

  • Otherwise

    • p[pu] := pv

    • sz[pv] := sz[pv] + sz[pu]

  • From the main method do the following −

  • n := size of arr

  • p := an array of size n

  • for initialize i := 0, when i < n, update (increase i by 1), do −

    • p[i] := i

  • sz := an array of size n and fill with 1

  • for initialize i := 0, when i < n, update (increase i by 1), do −

    • u := arr[i/2] / 2

    • v := arr[(i/2) OR 1] / 2

    • join(u, v)

  • ans := 0

  • for initialize i := 0, when i < n, update (increase i by 1), do −

    • if find(i) is same as i, then −

      • ans := ans + sz[i] − 1

    • return ans

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
vector<int> p, sz;
int find(int u) {
   return p[u] == u ? u : p[u] = find(p[u]);
}
void join(int u, int v) {
   int pu = find(u), pv = find(v);
   if (pu == pv)
   return;
   if (sz[pu] >= sz[pv]) {
      p[pv] = pu;
      sz[pu] += sz[pv];
   }else {
      p[pu] = pv;
      sz[pv] += sz[pu];
   }
}
int solve(vector<int>& arr) {
   int n = arr.size() / 2;
   p = vector<int>(n);
   for (int i = 0; i < n; ++i)
   p[i] = i;
   sz = vector<int>(n, 1);
   for (int i = 0; i < n; ++i) {
      int u = arr[i << 1] / 2;
      int v = arr[i << 1 | 1] / 2;
      join(u, v);
   }
   int ans = 0;
   for (int i = 0; i < n; ++i)
   if (find(i) == i)
   ans += sz[i] − 1;
   return ans;
}
int main(){
   vector<int> v = {0, 5, 6, 2, 1, 3, 7, 4};
   cout << solve(v);
}

Input

{2, 4, 6, 3}

Output

23

Updated on: 25-Dec-2020

110 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements