这道题刚开始做的时间没有思路,后来看了别人的思路后,写了自己的代码。
举例介绍:有向环
比如一组数据{5,4,3,2,1}; 如果按照正向排序,各个位置的下标为1,2,3,4,5,那么有向环为{5,1}{4,2}{3}一个3个。
思路:其实本道题就是找有向环,假如说有向环的数量为m,则需要交换的次数就为Array.size - m.同时本道题应该分为顺时针编号和逆时针编号,分别假定各个位置为其实位置,求有向环的个数,那么交换最少的次数便为Array.size- max(m)
代码1(我原始的思路,只是求出了2个方向,所有位置为起点的有向环的数量):
import java.util.Arrays;
public class MeettingWithAlien {
//uva 10570 外星人聚会
//0,5,2,3,4,1 0,5,4,3,2,1
private static int[] data = {0,5,2,3,4,1};
private static int[] visit = new int[data.length]; // 记录该位置是否已经被访问过
public static void main(String[] args) {
System.out.println("正序");
for (int i=1; i<data.length; i++){
System.out.println(getCircle(i));
}
System.out.println("逆序");
for (int i=1; i<data.length; i++){
System.out.println(getCircle2(i));
}
}
public static int getCircle2(int flag){//flag代表是 该位置是1号位置
int circleCount = 0; //用于 记录环的数量
Arrays.fill(visit, 0);
int position = 0; //当设置起点的时候,记录当前i在环中的真实位置
for (int i=1; i<data.length; i++){
position = getPosition2(flag, i); //当从新确定起点后,得到当前位置的真实位置
//看该位置value =index相等,同时保证该元素没有被访问过
if (visit[i] == 0 && position == data[i]){
++circleCount;
visit[i] = 1;
}else if (visit[i] == 0 && position != data[i]){
//如果该位置的元素没有被访问过,同时呢,该位置的value != index,那么dp寻找属于该环的元素
++circleCount;
dp2 (data[i],flag);
}
}
return circleCount;
}
public static int getCircle(int flag){//flag代表是 该位置是1号位置
int circleCount = 0; //用于 记录环的数量
Arrays.fill(visit, 0);
int position = 0; //当设置起点的时候,记录当前i在环中的真实位置
for (int i=1; i<data.length; i++){
position = getPosition(flag, i); //当从新确定起点后,得到当前位置的真实位置
//看该位置value =index相等,同时保证该元素没有被访问过
if (visit[i] == 0 && position == data[i]){
++circleCount;
visit[i] = 1;
}else if (visit[i] == 0 && position != data[i]){
//如果该位置的元素没有被访问过,同时呢,该位置的value != index,那么dp寻找属于该环的元素
++circleCount;
dp (data[i],flag);
}
}
return circleCount;
}
public static int getPosition(int m, int n){ //该函数的作用是如果指定m号位置为1号位置,那么n号位置应该为几号
if (n >= m){
return n - m + 1;
}else {
return n + data.length - m;
}
}
public static int getPosition2(int m,int n){ //当数数的方向为逆时针的时候
if (n > m){
return m + data.length - n;
}else {
return 1 + (m-n);
}
}
public static void dp (int n, int flag){ //flag代表的是编号为1的位置,
int position = flag + n - 1;
if (position >= data.length){
position = position - data.length + 1;
}
if (visit[position] == 1){
return;
}else {
visit[position] = 1;
dp(data[position], flag);
}
}
public static void dp2 (int n, int flag){ //flag代表的是编号为1的位置,
int position = flag - n + 1;
if (position <= 0){
position = flag - n + data.length;
}
if (visit[position] == 1){
return;
}else {
visit[position] = 1;
dp2(data[position], flag);
}
}
}