|
|
|
|
package class41;
|
|
|
|
|
|
|
|
|
|
// 来自小红书
|
|
|
|
|
// 一个无序数组长度为n,所有数字都不一样,并且值都在[0...n-1]范围上
|
|
|
|
|
// 返回让这个无序数组变成有序数组的最小交换次数
|
|
|
|
|
public class Code01_MinSwapTimes {
|
|
|
|
|
|
|
|
|
|
// 纯暴力,arr长度大一点都会超时
|
|
|
|
|
// 但是绝对正确
|
|
|
|
|
public static int minSwap1(int[] arr) {
|
|
|
|
|
return process1(arr, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 让arr变有序,最少的交换次数是多少!返回
|
|
|
|
|
// times, 之前已经做了多少次交换
|
|
|
|
|
public static int process1(int[] arr, int times) {
|
|
|
|
|
boolean sorted = true;
|
|
|
|
|
for (int i = 1; i < arr.length; i++) {
|
|
|
|
|
if (arr[i - 1] > arr[i]) {
|
|
|
|
|
sorted = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (sorted) {
|
|
|
|
|
return times;
|
|
|
|
|
}
|
|
|
|
|
// 数组现在是无序的状态!
|
|
|
|
|
if (times >= arr.length - 1) {
|
|
|
|
|
return Integer.MAX_VALUE;
|
|
|
|
|
}
|
|
|
|
|
int ans = Integer.MAX_VALUE;
|
|
|
|
|
for (int i = 0; i < arr.length; i++) {
|
|
|
|
|
for (int j = i + 1; j < arr.length; j++) {
|
|
|
|
|
swap(arr, i, j);
|
|
|
|
|
ans = Math.min(ans, process1(arr, times + 1));
|
|
|
|
|
swap(arr, i, j);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ans;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void swap(int[] arr, int i, int j) {
|
|
|
|
|
int tmp = arr[i];
|
|
|
|
|
arr[i] = arr[j];
|
|
|
|
|
arr[j] = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 已知arr中,只有0~n-1这些值,并且都出现1次
|
|
|
|
|
public static int minSwap2(int[] arr) {
|
|
|
|
|
int ans = 0;
|
|
|
|
|
for (int i = 0; i < arr.length; i++) {
|
|
|
|
|
while (i != arr[i]) {
|
|
|
|
|
swap(arr, i, arr[i]);
|
|
|
|
|
ans++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ans;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 为了测试
|
|
|
|
|
public static int[] randomArray(int len) {
|
|
|
|
|
int[] arr = new int[len];
|
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
|
arr[i] = i;
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
|
swap(arr, i, (int) (Math.random() * len));
|
|
|
|
|
}
|
|
|
|
|
return arr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
int n = 6;
|
|
|
|
|
int testTime = 2000;
|
|
|
|
|
System.out.println("测试开始");
|
|
|
|
|
for (int i = 0; i < testTime; i++) {
|
|
|
|
|
int len = (int) (Math.random() * n) + 1;
|
|
|
|
|
int[] arr = randomArray(len);
|
|
|
|
|
int ans1 = minSwap1(arr);
|
|
|
|
|
int ans2 = minSwap2(arr);
|
|
|
|
|
if (ans1 != ans2) {
|
|
|
|
|
System.out.println("出错了!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
System.out.println("测试结束");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|