数组中的逆序对

来源:互联网 发布:马原人工智能与意识 编辑:程序博客网 时间:2024/06/05 17:30

题目

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

解题

方法一:暴力

public class Solution {    public int InversePairs(int [] array) {        if(array == null || array.length <=1)            return 0;        int count = 0;        int len = array.length;        for(int i=0;i<len;i++){            for(int j=i+1;j<len;j++){                if(array[i] > array[j]){                    count ++;                }            }        }        return count;    }}

方法二:归并排序

public class Solution {    public int InversePairs(int [] array) {         if(array.length<=0)             return 0;         return mergeSort(array,0,array.length-1);     }     public int  mergeSort(int[] array,int l,int r){         if(l>=r){             return 0;         }         int mid=(l+r)/2;         int lnums=mergeSort(array,l,mid);         int rnums=mergeSort(array,mid+1,r);        return  lnums+rnums+merge(array,l,mid,r);     }     public int merge(int[] array,int l,int mid,int r){        int [] temp = new int[r-l+1];        int count=0;        int i=l;        int j=mid+1;        int t=0;        while(i<=mid && j<=r){            if(array[i]>array[j]){ // 说明:i - mid 内的数都大于 array[j]                temp[t++]=array[j];                count+=mid-i+1; // 计算逆序对个数                j++;            }else {                temp[t++]=array[i];                i++;            }        }        // 剩余的数补上去         // i越界了 增加 j        while(i>mid&&j<=r){             temp[t++]=array[j];             j++;        }         // j越界了 增加 i        while(i<=mid&&j>r){            temp[t++]=array[i];            i++;        }        // 利用temp数组更新array数组         for(i=l;i<=r;i++){            array[i]=temp[i-l];        }        return count;     }}

题目进行了更新,测试数据量更多
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5

更新程序

public class Solution {    public int InversePairs(int [] array) {         if(array.length<=0)             return 0;         return (int)(mergeSort(array,0,array.length-1)%1000000007);     }     public long  mergeSort(int[] array,int l,int r){         if(l>=r){             return 0;         }         int mid=(l+r)/2;         long lnums=mergeSort(array,l,mid)%1000000007 ;         long rnums=mergeSort(array,mid+1,r)%1000000007 ;        return  lnums+rnums+merge(array,l,mid,r);     }     public long merge(int[] array,int l,int mid,int r){        int [] temp = new int[r-l+1];        long count=0;        int i=l;        int j=mid+1;        int t=0;        while(i<=mid && j<=r){            if(array[i]>array[j]){ // 说明:i - mid 内的数都大于 array[j]                temp[t++]=array[j];                count+=mid-i+1; // 计算逆序对个数                j++;            }else {                temp[t++]=array[i];                i++;            }        }        while(i>mid&&j<=r){             temp[t++]=array[j];             j++;        }        while(i<=mid&&j>r){            temp[t++]=array[i];            i++;        }        for(i=l;i<=r;i++){            array[i]=temp[i-l];        }        return count%1000000007;     }}
0 0