如何找到对具有重复元素的数组进行排序所需的最小交换数?

时间:2019-12-26 16:14:57

标签: arrays algorithm sorting

我遇到了一种算法,用于找出对没有重复元素的数组进行排序的最小交换量。当数组中有重复的元素时,情况变得很有趣。让我们假设该数组可以包含-2 ^ 31-(2 ^ 31)-1的整数元素。同样,数组可以包含重复的元素。找出最小交换数量的最佳方法是什么?

注意:实际上,我并不是要对数组进行排序,而是要找出使它按升序排列的最小交换数。

更新:我不担心稳定性。也可以是任意交换。

2 个答案:

答案 0 :(得分:0)

int minSwaps(int arr[], int n) 
{ 
    // Create an array of pairs where first 
    // element is array element and second element 
    // is position of first element 
    pair<int, int> arrPos[n]; 
    for (int i = 0; i < n; i++) 
    { 
        arrPos[i].first = arr[i]; 
        arrPos[i].second = i; 
    } 

    // Sort the array by array element values to 
    // get right position of every element as second 
    // element of pair. 
    sort(arrPos, arrPos + n); 

    // To keep track of visited elements. Initialize 
    // all elements as not visited or false. 
    vector<bool> vis(n, false); 

    // Initialize result 
    int ans = 0; 

    // Traverse array elements 
    for (int i = 0; i < n; i++) 
    { 
        // already swapped and corrected or 
        // already present at correct pos 
        if (vis[i] || arrPos[i].second == i) 
            continue; 

        // find out the number of  node in 
        // this cycle and add in ans 
        int cycle_size = 0; 
        int j = i; 
        while (!vis[j]) 
        { 
            vis[j] = 1; 

            // move to next node 
            j = arrPos[j].second; 
            cycle_size++; 
        } 

        // Update answer by adding current cycle.  
        if (cycle_size > 0) 
        { 
            ans += (cycle_size - 1); 
        } 
    } 

// Return result 
    return ans; 
} 

答案 1 :(得分:0)

这是NP完全的,此问题与欧拉图的最大边不相交循环覆盖之间有多项式折减(双向)。第二个问题是关于找到欧拉图的最大边缘分区,以使每个分区形成一个循环。您可以在这里看到这是NP完整的:https://arxiv.org/pdf/1708.09141.pdf