数组中的逆序对

题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

输入描述:

题目保证输入的数组中没有的相同的数字
数据范围: 对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5

示例1
输入

1,2,3,4,5,6,7,0

输出

7

方法一
最直观的一种方法就是顺序扫描整个数组,没扫描一个数字,就逐个比较该数字和他后面的数字的大小,看是否存在逆序对。但是这种方法的时间复杂度很大O(n2n^2),这道题也表明了数据量很大,所以存在超时的可能。

    public int InversePairs(int [] array) {
        if(array == null || array.length <= 1) {
        	return 0;
        }
        
        int times = 0;
        for (int i = 0; i < array.length; i++) {
			for (int j = i + 1; j < array.length; j++) {
				if(array[i] > array[j]) {
					++times;
				}
			}
		}
        
        return times % 1000000007;
    }

方法二
采用归并排序的思想:
如果对归并不太熟悉的可以看这篇文章:归并排序的理解和实现(Java)

把数据分成前后两个数组(递归分到每个数组仅有一个数据项),合并数组。
合并时,出现前面的数组值array[i]大于后面数组值array[j]时,则前面数组array[i]~array[mid]都是大于array[j]的,count += mid+1 - i (核心思想)

其次,测试用例输出结果比较大,对每次返回的count mod (1000000007)求余

    public int times = 0;
    
    public int InversePairs_2(int [] array) {
        if(array != null && array.length > 0) {
        	mergeSortUp2Down(array, 0, array.length - 1);
        }
        return times;
        
    }
    
    public void mergeSortUp2Down(int[] elem, int start, int end) {
    	if(start >= end) {
    		return;
    	}
    	int mid = (start + end) / 2;
    	
    	mergeSortUp2Down(elem, start, mid);
    	mergeSortUp2Down(elem, mid + 1, end);
    	
    	merge(elem, start, mid, end);
    }
    
    public void merge(int[] elem, int start, int mid, int end) {
    	int[] temp = new int[end - start + 1];
    	int i = start;
    	int j = mid + 1;
    	int k = 0;
    	while(i <= mid && j <= end) {
    		if(elem[i] <= elem[j]) {
    			temp[k++] = elem[i++];
    		}
    		else {
    			temp[k++] = elem[j++];
    			times += mid - i + 1; // core code, calculate InversePairs
    			times %= 1000000007;
    		}
    	}
    	
    	while(i <= mid) {
    		temp[k++] = elem[i++];
    	}
    	
    	while(j <= end) {
    		temp[k++] = elem[j++];
    	}
    	
    	for (i = 0; i < k; i++) {
			elem[start + i] = temp[i];
		}
    	temp = null;
    } 
posted @ 2019-03-27 22:12  如是说  阅读(825)  评论(0编辑  收藏  举报