算法练习 逆序对

算法练习 逆序对

逆序对问题算是很经典了,最简单的暴力破解时间复杂度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");

在这里插入图片描述
害!可能是我自己写的一次归并算法不好,一百万条数据竟然要用一分钟。。。

先这么着吧!拜了个拜!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章