并查集
    1.首先初始状态把这N对情侣分别构成一个连通块
    2.考虑k对情侣相互错开的情况,他们形成一个环,可以知道需k-1次交换使排列正确
    3.这样相互错开的情况,分别构成连通块,最后用N - 连通块个数即为答案
    例如:0,1|2,3|… |2N-2,2N-1
    |0 3| … |7 2|…|6 1| 看相对顺序,可以发现这三对构成一个环,只需2次交换
    同理还有其他类型的环构成连通块

    1. vector<int> pre;
    2. void init(int n){
    3. for(int i = 0;i < n;i += 2){
    4. pre.push_back(i);
    5. pre.push_back(i);
    6. }
    7. }
    8. int find(int x){
    9. if(x == pre[x]) return x;
    10. // 路径压缩
    11. else{
    12. pre[x] = find(pre[x]);
    13. return pre[x];
    14. }
    15. }
    16. int minSwapsCouples(vector<int>& row) {
    17. if(row.empty())return 0;
    18. int n = row.size();
    19. init(n);
    20. for (int i = 0; i < n; i += 2) {
    21. pre[find(row[i + 1])] = find(row[i]);
    22. }
    23. int res = n / 2;
    24. //每有一个连通块,会减少一次交换次数
    25. for (int i = 0; i < n; i ++) {
    26. if (pre[i] == i) res --;
    27. }
    28. return res;
    29. }