You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.0 KiB

2 years ago
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("测试结束");
}
}