归并排序求逆序对的个数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qiaojun1234567/article/details/48860179

逆序对的定义: 如果 A[i] > A[j]  并且 i < j 那么 这就是一个逆序对。如何求一个整型数组中逆序对的个数?我们可以利用归并排序来实现。

public class Solution {
    int sum ;
    //返回一个数组的逆序个数
    public int InversePairs(int [] array) {
        sum = 0;
        mergeSort(array, 0, array.length - 1);
        return sum;
       
    }
    
    // 归并排序
    //合并 A[p..q] 与 A[q + 1, r];
    public int merge(int [] A, int p, int q, int r) {
        int i,j,k;
        int cnt = 0;
        int n1 = q - p + 1;
        int n2 = r - q;
        // 创建两个数组存储 要合并的 左右两部分
        int left[] = new int[n1 +1];
        int right[] = new int[n2 + 1];
        for(i = 0; i < n1; i++)
            left[i] = A[p + i];
        for(j = 0; j < n2; j++) {
            right[j] = A[ q + 1 + j];
        }
        
        left[n1] = Integer.MAX_VALUE;// 哨兵
        right[n2] = Integer.MAX_VALUE;//哨兵
        
        k = p;
        i = 0;
        j = 0;
        // 开始合并 
        // 我们合并的是left[0~n1] 与 right[0 ~ n2];
        // 如果 left[i] <= right[j] 那么 说明right[0 ~ j -1] 都小于 left[j];
        // 所以 小鱼left[i] 的逆序个数就是 j;
        while(k <= r) {
            // 左边 小于 邮编
            if(left[i] <= right[j]) {
                A[k++] = left[i];
                i++;
                cnt += j;
                
            }else{
                A[k++] = right[j];
                
                j++;
            }
                
        }
        return cnt;
    }
     // 归并排序
    public void mergeSort(int A[], int l, int r) {
        
        if(l < r) {
            int m = (l + r) /2;
            mergeSort(A, l,m);
            mergeSort(A, m + 1, r);
            sum +=merge(A, l, m, r);
        }
    }
}


猜你喜欢

转载自blog.csdn.net/qiaojun1234567/article/details/48860179
今日推荐