【本文链接】
http://www.cnblogs.com/hellogiser/p/inversion-pairs-by-merge-sort.html
【题目】
编程之美1.7光影切割问题可以进一步将问题转化为求逆序数问题。
【分析】
求解逆序对问题与MergeSort类似,只需要对MergeSort稍作修改即可实现。MergeSort是采用分治法的思想,若需要排序A[p...r],则可以对半分成A[p...q]和A[q...r],然后将这有序的两部分Merge,而Merge的过程为Θ(n)的时间复杂度。根据主定率T(n)=2(Tn/2)+Θ(n),时间复杂度为T(n)=Θ(nlgn)。
同理,求整个序列中的逆序对,也可以利用分治法的思想,即
逆序对(A[p...r])= 逆序对(A[p...q])+逆序对(A[q...r])+逆序对(A[p...q], A[q...r]之间)。
结合MergeSort,关键是如何在Θ(n)的时间有效的求出A[p...q], A[q...r]之间的逆序对。因为在合并排序的Merge过程中,A[p...q]和A[q...r]已经有序,假设此时已经Merge到A[i...q]和A[j...r]。考虑接下来的一步:如果A[i]<=A[j],说明A[i]比后面的序列A[j...r]中的元素都小,不存在逆序对;如果A[i]>A[j],,则说明A[j]比前面的序列A[i...q]都小,即以j结尾的逆序对的数量为前面的序列剩余序列A[i...q]中元素的数量。
Merge的过程中即可得到A[p...r], A[r...q]之间的逆序对的数量,时间复杂度亦为Θ(n), 由主定律总的时间复杂为 Θ(nlgn),这种方法要比朴素的方法 Θ(n*n)好很多。
【MergeSort】
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
/*
version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/25 */ void merge(int *A, int p, int q, int r) { //Li: p...q Rj: q+1...r ; ; ]; ]; // copy L and R ; i < n1; i++) L[i] = A[p + i]; ; j < n2; j++) R[i] = A[q + + j]; // mark end L[n1] = INT_MAX; R[n2] = INT_MAX; ; // left ; // right ; // whole for (k = p; k <= r; k++) { if (L[i] <= R[j]) { A[k] = L[i]; i++; } else { // L[i]>R[j] A[k] = R[j]; j++; } } delete []L; void merge_sort(int *A, int p, int r) void MergeSort(int *A, int n) |
[InversionPair]
inversionPair只需要在merge函数中增加3行代码记录即可。先将inversion_pairs初始化为0,当L[i]>R[j]时,更新inversion_pairs=inversion_pairs+(n1-i),最后返回即可。同时在merge_sort中返回left_pair,right_pair和corss_pair之和即可。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
/*
version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/25 */ int merge_pair(int *A, int p, int q, int r) { //Li: p...q Rj: q+1...r ; ; ]; ]; // copy L and R ; i < n1; i++) L[i] = A[p + i]; ; j < n2; j++) R[i] = A[q + + j]; // mark end L[n1] = INT_MAX; R[n2] = INT_MAX; ; // left ; // right ; // whole //============================ ; //============================ for (k = p; k <= r; k++) { if (L[i] <= R[j]) { A[k] = L[i]; i++; } else { // L[i]>R[j] A[k] = R[j]; j++; //============================ inversion_pairs += (n1 - i); //============================ } } delete []L; int inversion_pair(int *A, int p, int r) int InversionPair(int *A, int n) |
【链接】
http://www.cnblogs.com/bovine/archive/2011/09/22/2185006.html
http://blog.csdn.net/zhanglei8893/article/details/6230233
【本文链接】
http://www.cnblogs.com/hellogiser/p/inversion-pairs-by-merge-sort.html