算法练习 逆序对
逆序对问题算是很经典了,最简单的暴力破解时间复杂度O(n2),时间复杂度大于O(n2)的算法是非常糟糕了,所以我们采用归并排序的算法改动一下,即可获得O(nlogn)的算法。
逆序对定义:数列中如果 i < j && arr[i] > arr[j],则arr[i]和arr[j]为一对逆序对。
- java算法参考
// 逆序对个数
private static long ropCount = 0;
/**
* 计算逆序对
*
* @param arr
* @param left
* @param right
*/
public static void calcRop(int[] arr, int left, int right) {
if (left >= right)
return;
int mid = (left + right) >>> 1;
calcRop(arr, left, mid);
calcRop(arr, mid + 1, right);
calc(arr, left, mid, right);
}
/**
* 一次计算
*
* @param arr
* @param left
* @param mid
* @param right
*/
public static void calc(int[] arr, int left, int mid, int right) {
int i = left;
int j = mid + 1;
while (i < j && j <= right) {
while (i < j && arr[i] <= arr[j])
i++;
ropCount += j - i;
int temp = arr[j];
System.arraycopy(arr, i, arr, i + 1, j - i);
arr[i] = temp;
i++;
j++;
}
}
- 算法测试
正确性测试
有那么几组数据
数据 | 逆序对的数量 |
---|---|
{ 9, 8, 7, 5, 2, 4, 5, 6 } | 20 |
{ 7, 5, 5, 4, 3, 3, 5, 4, 4, 1, 6 } | 32 |
{ 9, 8, 7, 1, 2, 3, 4, 3, 2, 1 } | 33 |
{ 7, 5 } | 1 |
{ 5, 5 } | 0 |
{ 5 } | 0 |
{ } | 0 |
分别跑起来,结果都对的上,暂未发现结果不符的数据。
压力测试
跑一百万条数据,看看用时。
int[] arr = new int[1000*1000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100 + 1);
}
long start = System.currentTimeMillis();
calcRop(arr, 0, arr.length - 1);
System.out.println(ropCount);
long end = System.currentTimeMillis();
System.out.println("一百万条数据用时:" + (end-start)/1000 + "s");
害!可能是我自己写的一次归并算法不好,一百万条数据竟然要用一分钟。。。
先这么着吧!拜了个拜!