我所看到的问题如下:任何人对此都有所了解? http://judgecode.com/problems/1011
给定从0到n - 1的整数排列,对它们进行排序很容易。但是,如果你每次只能交换一对整数呢?
请计算掉期的最小数量
答案 0 :(得分:1)
一种经典算法似乎是置换周期(https://en.wikipedia.org/wiki/Cycle_notation#Cycle_notation)。需要的交换次数等于减去周期数的元素总数。
例如:
1 2 3 4 5
2 5 4 3 1
Start with 1 and follow the cycle:
1 down to 2, 2 down to 5, 5 down to 1.
1 -> 2 -> 5 -> 1
3 -> 4 -> 3
我们需要将索引1与5交换,然后将索引5与2交换;以及索引为3的索引3.共有3个交换或n - 2
。我们将循环次数减去n
,因为循环元素总共n
,并且每个循环代表的交换小于其中元素的数量。
答案 1 :(得分:1)
以上是C
中针对上述问题的简单实现。该算法类似于用户גלעדברקן:
a[]
中每个元素的位置存储在b[]
中。所以,b[a[i]] = i
a[]
。i
位置,检查a[i]
是否等于i
。如果yes
,则继续迭代。no
,则交换时间。仔细查看代码中的逻辑,看看如何进行交换。 这是最重要的一步,因为需要修改数组a[]
和b[]
。增加互换count
。 以下是实施:
long long sortWithSwap(int n, int *a) {
int *b = (int*)malloc(sizeof(int)*n); //create a temporary array keeping track of the position of every element
int i,tmp,t,valai,posi;
for(i=0;i<n;i++){
b[a[i]] = i;
}
long long ans = 0;
for(i=0;i<n;i++){
if(a[i]!=i){
valai = a[i];
posi = b[i];
a[b[i]] = a[i];
a[i] = i;
b[i] = i;
b[valai] = posi;
ans++;
}
}
return ans;
}
答案 2 :(得分:1)
解决这个问题的实质在于以下观察
1.数组中的元素不重复
2.元素范围从0到n-1,其中n是数组的大小。
接近的方式
在了解了解决问题的方法之后,您可以在线性时间内解决问题。
想象一下,在对所有条目进行排序后,数组会如何?
对于所有条目,它看起来像arr [i] == i。这有说服力吗?
首先创建一个名为FIX的bool数组,其中FIX [i] ==如果第i个位置是固定的,则为true,初始化该数组为false
开始检查匹配arr [i] == i的原始数组,直到这个条件成立为止,eveything正常。在继续遍历数组的同时也更新FIX [i] = true。
当你发现arr [i]!= i
你需要做某事的那一刻,arr [i]必须有一些值x使得x>我,我们如何保证?保证来自于数组中的元素不重复的事实,因此如果数组被排序到索引i,则意味着数组中位置i处的元素不能来自左边而是来自右边。
现在值x本质上是关于某个索引,为什么如此,因为数组只有从0开始的n-1元素,并且在排序的arry中,数组的每个元素i必须位于位置i。
arr [i] == x意味着什么,不仅元素i不在它的正确位置,而且元素x也从它的位置缺失。
现在要修复第i个位置,你需要查看第x个位置,因为可能第x个位置保持i然后你将交换索引i和x的元素,并完成工作。
但是等等,它是索引x不需要保持i(并且你只需1次交换即可完成这些位置的修复)。相反,索引x可能保持值y,这也将大于i,因为数组仅排序到位置i。
现在你可以修复位置i,你需要修复x,为什么?我们稍后会看到。
所以现在再次尝试修复位置x,然后类似地你会尝试修复,直到你不知道时间某个位置的元素i告诉你。
时尚是遵循arr [i]的链接,直到你在某个索引处点击元素i。
保证你肯定会在某个地方打我,同时跟着这个方式。为什么?尝试证明它,做一些例子,你会感觉到它
现在,您将开始修复您在索引i之后的路径中看到的所有索引,直到此索引(比如说j)。现在您所看到的是您所遵循的路径是循环路径,对于每个索引i,arr [i]都是它的先前索引(从此处到达的索引),并且一旦看到您可以修复索引,并将FIX数组中的所有索引标记为true。现在继续使用数组的下一个索引并执行相同的操作,直到修复整个数组。
这是完整的想法,但只是没有。交换,你可以看到,一旦你找到了n个元素的循环,你需要n个交换,然后你修复数组,然后再继续。那么你将如何计算这个数字。互换。
如果您对此方法有疑问,请告诉我。
您也可以要求提供C / C ++代码帮助。
乐意提供帮助: - )