LintCode 逆序对

来源:互联网 发布:材料预算软件 编辑:程序博客网 时间:2024/06/16 02:37

在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。给你一个数组,求出这个数组中逆序对的总数。
概括:如果a[i] > a[j] 且 i < j, a[i] 和 a[j] 构成一个逆序对。

样例
序列 [2, 4, 1, 3, 5] 中,有 3 个逆序对 (2, 1), (4, 1), (4, 3),则返回 3 。

1.直接暴力求解,找到所有对,检查是不是逆序的。
2.利用归并排序的思想,在合并左右两部分(左部分B[left,mid],右部分C[mid+1,right])时,如果左部分的数B[i]比右部分的数C[j]大,那么结果res直接加上(mid-left)-i+1,因为左部分已经有序了,(B[i],C[j])是逆序对,那么B[i]后面的数和C[j]也构成逆序对,注意数组的下标边界。。。。。。
代码如下:

public class Solution {    /*     * @param A: an array     * @return: total of reverse pairs     */    public long reversePairs(int[] A) {        // write your code here        long[] res=new long[1];        mergeSort(A,0,A.length-1,res);        return res[0];    }    public void mergeSort(int[] A,int l,int r,long[] res){        if(l>=r){            return;        }        int mid=(l+r)/2;        mergeSort(A,l,mid,res);        mergeSort(A,mid+1,r,res);        merge(A,l,r,mid,res);    }    public void merge(int[] A,int l, int r,int mid,long[] res){        int[] B=new int[mid-l+1];        int[] C=new int[r-mid];        for(int i=0;i<mid-l+1;i++){            B[i]=A[l+i];        }        for(int i=0;i<r-mid;i++){            C[i]=A[mid+1+i];        }        int i=0,j=0,k=l;        while(i<mid-l+1 &&j<r-mid){            if(B[i]<=C[j]){                A[k++]=B[i++];            }            else{                res[0]+=mid-l-i+1;                A[k++]=C[j++];            }        }        while(i<mid-l+1){            A[k++]=B[i++];        }        while(j<r-mid){            A[k++]=C[j++];        }    }}
原创粉丝点击