描述
给出一个无序数列,每次只能交换相邻两个元素,求将原数列变成递增数列的最少交换次数。 如:数列:2,3,1,交换3和1后变成:2,1,3;交换1和2之后变成:1,2,3。总共交换2次。
输入样例
2,3,1
输出样例
2
我的代码
private static String solution(String line) {
// 在此处理单行数据
String[] array = line.split(",");
int[] array1 = new int[array.length];
for (int i = 0; i < array1.length; i++) {
array1[i] = Integer.parseInt(array[i]);
}
int result = sort(array1);
// 返回处理后的结果
return result + "";
}
private static int sort(int []arr){
int []temp = new int[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
return sort(arr,0,arr.length-1,temp);
}
private static int sort(int[] arr,int left,int right,int []temp){
if(left<right){
int mid = (left+right)/2;
int count = 0;
count += sort(arr,left,mid,temp);//左边归并排序,使得左子序列有序
count += sort(arr,mid+1,right,temp);//右边归并排序,使得右子序列有序
count += merge(arr,left,mid,right,temp);//将两个有序子数组合并操作
return count;
}
return 0;
}
private static int merge(int[] arr,int left,int mid,int right,int[] temp){
int i = left; // 左序列指针
int j = mid+1; // 右序列指针
int t = left; // 临时数组指针
int count = 0;
while (i<=mid && j<=right){
if(arr[i]<=arr[j]){ // 此处为稳定排序的关键,不能用小于
temp[t++] = arr[i++];
}else {
temp[t++] = arr[j++];
count+=j-t; //每当后段的数组元素提前时,记录提前的距离(有几个数大于当前处于j位置的数)
}
}
while(i<=mid){ // 将左边剩余元素填充进temp中
temp[t++] = arr[i++];
}
while(j<=right){ // 将右序列剩余元素填充进temp中
temp[t++] = arr[j++];
}
t = left;
// 将temp中的元素全部拷贝到原数组中
while(left <= right){
arr[left++] = temp[t++];
}
return count;
}
说明
这题其实就是求一串数字的逆序数,本解决方法采用的是归并排序算法求逆序数,归并排序算法参考博客:博客园 dreamcatcher-cx 的 图解排序算法(四)之归并排序
(咳咳,我完全就是拿他写的归并排序算法,然后改了一点东西)