输入样例1:
5
3 1 2 5 4
输出样例1:
3
输入样例2:
5
5 4 3 2 1
输出样例2:
2
解题思路:
将瓶子存入数组b中,b[i] = j:表示第i个位置放的j号瓶子。将瓶子想象为图中的每个点,连边方式为:瓶子连向该瓶子本来应该在的位置上的瓶子。即开始时,瓶子应该是形成若干个环,排好序时,环的个数就是瓶子的个数(都是自环)。
当交换同一环内的两个瓶子时,环的个数会加一;当交换不同环上的瓶子时,环的数量会减一。
求最少交换的次数就等价于当前环需要交换多少次可以都形成自环。
Java代码:
import java.io.*;
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String[] split = br.readLine().split(" ");
int []battle = new int[n + 1]; //b[i] = j:表示第i个位置放的j号瓶子
boolean []tag = new boolean[n + 1]; //标记是否访问过
for(int i = 1; i <= n; i++)
battle[i] = Integer.parseInt(split[i - 1]);
int ans = 0; //环的个数
for(int i = 1; i <= n; i++) {
if(!tag[i]) {
ans++;
for(int j = i; !tag[j]; j = battle[j]) //遍历完整个环
tag[j] = true;
}
}
System.out.println(n - ans); //自环数减现有环数
}
}