最小掉期2-按升序对向量进行排序所需的最小掉期数

时间:2019-12-22 16:21:54

标签: c++

我正在做一个相当简单的HackerRank测试,要求用户编写一个函数,该函数返回按升序对无序向量进行排序所需的最小交换次数。

开始:1、2、5、4、3

末尾:1、2、3、4、5

最小互换次数:1

我编写了一个可在13/14测试用例上使用的函数,但对于最终用例来说太慢了。

#include<iostream>
#include<vector>

using namespace std;


int mimumumSwaps(vector<int> arr) {
    int p = 0;  // Represents the (index + 1) of arr, e.g. 1, 2, ..., arr.size() + 1 
    int swaps = 0;

    for (vector<int>::iterator i = arr.begin(); i != arr.end(); ++i) {
        p++;
        if (*i == p)    // Element is in the correct place
            continue;
        else{   // Iterate through the rest of arr until the correct element is found
            for (vector<int>::iterator j = arr.begin() + p - 1; j != arr.end(); ++j) {
                if (*j == p) {  
                    // Swap the elements
                    double temp = *j;
                    *j = *i;
                    *i = temp;

                    swaps++;
                    break;
                }
            }
        }
    }
    return swaps;
}


int main()
{
    vector<int> arr = { 1, 2, 5, 4, 3 };

    cout << mimumumSwaps(arr);

}

我将如何进一步加快速度?

我可以导入什么功能来加快我的流程吗?

有没有一种方法,而无需实际交换任何元素并简单地计算出最小值。我认为交换会加快处理时间?

2 个答案:

答案 0 :(得分:1)

可以将所有排列分解为循环子集。找到所说的子集。

将K个元素的子集旋转1将进行K-1个交换。

遍历数组,直到找到不适当的元素。继续执行该循环,直到完成为止。前进,跳过已经放入循环中的元素。每个周期的总和(大小为1)。

要跳过,维护有序或无序的一组未检查项目,并在检查它们时快速删除它们。

我认为这样可以在O(n lg n)左右提供最佳交换计数。

答案 1 :(得分:-1)

#include <bits/stdc++.h>
#include <vector>
#include <algorithm>

using namespace std;

int minimumSwaps(vector<int> arr)
{
    int i,c,j,k,l;
    
    j=c=0;
    l=k=arr.size();
       
        while (j<k)
        {
            i=0;
                while (i<l)
                {
                     if (arr[i]!=i+1)
                     {
                         swap(arr[i],arr[arr[i]-1]);
                         c++;
                     }    

                  i++;

                }

         k=k/2;
         j++;

        }

return c;

}

int main()
{
    int n,q;
    cin >> n;
    
    vector<int> arr;
    
    for (int i = 0; i < n; i++)
    {
        cin>>q;
        arr.push_back(q);
    }
    
    int res = minimumSwaps(arr);
    cout << res << "\n";

return 0;
}