置换环:求解数组排序元素间所需最小交换次数这类问题。
置换环思想:置换环将每个元素指向其排序后应在的位置,最终首位相连形成一个环(若数字在最终位置,则其自身成环),可知元素之间的交换只会在同一个环内进行,而每个环内的最小交换次数为环上元素个数-1。最终排序所需最小交换次数为数组长度-环的个数。
代码实现:
int n;
cin >> n;
vector<int> p(n), vis(n, 0); //p记录位置,vis标记是否在环中
for (int i = 0; i < n; i++) {
int a;
cin >> a;
a--;
p[a] = i;
}
int cnt = 0; //有多少个环
for (int i = 0; i < n; i++) {
if(vis[i]) continue;
int j = i;
while(!vis[j]) {
vis[j] = cnt + 1;
j = p[j];
}
cnt++;
}
cout << n - cnt << endl; //求最少交换次数