我遇到了一种算法,用于找出对没有重复元素的数组进行排序的最小交换量。当数组中有重复的元素时,情况变得很有趣。让我们假设该数组可以包含-2 ^ 31-(2 ^ 31)-1的整数元素。同样,数组可以包含重复的元素。找出最小交换数量的最佳方法是什么?
注意:实际上,我并不是要对数组进行排序,而是要找出使它按升序排列的最小交换数。
更新:我不担心稳定性。也可以是任意交换。
答案 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