Java学习手册:(数据结构与算法-数组)如何求解数组中反序对的个数?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/MaybeForever/article/details/102470872

问题描述:

给定一个数值a,如果a[i]>a[j](i<j),那么a[i]与a[j]被称为一个反序,例如,给定数组{1,5,3,2,6},共有(5,3)、(5,2)和(3,2)三个反序对。

方法一:

暴力法,遍历数组并与其后一个数字比较。时间复杂度:O(n^2)。

方法一代码如下:

package com.haobi;

public class Test30 {
	public static void main(String[] args) {
		int[] array = {1,5,3,2,6};
		System.out.println(reverseCount(array));
	}
	
	public static int reverseCount(int[] a) {
		int count = 0;
		int len = a.length;
		for(int i=0;i<len;i++) {
			for(int j=i+1;j<len;j++) {
				if(a[i]>a[j]) {
					count++;
				}
			}
		}
		return count;
	}
}

程序输出结果如下:

3

方法二:

分治归并法。参考归并排序方法,在归并排序的基础上额外使用一个计数器来记录逆序对的个数。时间复杂度:O(nlogn)。

方法二代码如下:

package com.haobi;

public class Test31 {
	
	public static int reverseCount = 0;
	
	public static void main(String[] args) {
		int[] array = {1,5,3,2,6};
		merge_sort(array, 0, array.length-1);
		System.out.println(reverseCount);
	}
	
	public static void merge_sort(int[] a, int begin, int end) {
		if(begin < end) {
			int mid = begin+(end-begin)/2;
			merge_sort(a, begin, mid);
			merge_sort(a, mid+1, end);
			merge(a, begin, mid, end);
		}
	}
	
	public static void merge(int[] a, int begin, int mid, int end) {
		int i,j,k,n1,n2;
		n1 = mid-begin+1;//前半段的长度
		n2 = end-mid;//后半段的长度
		int[] L = new int[n1];
		int[] R = new int[n2];
		//前半段开始遍历并赋值
		for(i=0,k=begin;i<n1;i++,k++) {
			L[i] = a[k];
		}
		//后半段开始遍历
		for(i=0,k=mid+1;i<n2;i++,k++) {
			R[i] = a[k];
		}
		//归并排序操作
		for(k=begin,i=0,j=0;i<n1&&j<n2;k++) {
			if(L[i]<R[j]) {
				a[k] = L[i++];
			}else {
				//统计逆序对个数
				//reverseCount += mid-k+1;//?
                reverseCount += n1-i;
				a[k] = R[j++];
			}
		}
		if(i<n1) {
			for(j=i;j<n1;j++,k++) {
				a[k] = L[j];
			}
		}
		if(j<n2) {
			for(i=j;i<n2;i++,k++) {
				a[k] = R[i];
			}
		}
	}
}

程序输出结果如下:

3

猜你喜欢

转载自blog.csdn.net/MaybeForever/article/details/102470872
今日推荐