Java 求解数组中的逆序对

来源:互联网 发布:李政道和杨振宁知乎 编辑:程序博客网 时间:2024/06/06 08:23

题目:

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

解题思路:本题最直观的方法是使用双重循环遍历数组,每遍历一个值便将其与后面的元素比较,这种解法的算法复杂度为O(n^2),下面提供一种复杂度为O(n)的算法,主要是借助归并排序的思想,先分治,每次合并的时候进行逆序对的计数

public class Solution {    int count = 0;    public int InversePairs(int [] array) {        return mergeSort(array,0,array.length-1);    }    public int mergeSort(int[] array,int low,int high){        if(low<high){            int middle = (low+high)/2;            mergeSort(array,low,middle);            mergeSort(array,middle+1,high);            count = count+merge(array,low,middle,high);        }        return count;    }    public int merge(int[] array,int low,int middle,int high){        int i,j,k;        //逆序对计数变量        int count = 0;        int n1 = middle-low+1;        int n2 = high-middle;        int[] L = new int[n1];        int[] R = new int[n2];        for(i=0,k=low;i<n1;i++,k++){            L[i] = array[k];        }        for(i=0,k=middle+1;i<n2;i++,k++){            R[i] = array[k];        }        for(i=0,j=0,k=low;i<n1&&j<n2;k++){            if(L[i]<R[j]){                array[k] = L[i];                i++;            }else{                if(L[i]>=R[j]){                    int tempCount = 0;                    while(i<n1&&L[i]==R[j]){                        i++;                        tempCount++;                    }                    count = count+n1-i;                    i = i-tempCount;                }                array[k] = R[j];                j++;            }        }        if(i<n1){//          count = count+n1-i-1;            for(j=i;j<n1;j++,k++){                array[k] = L[j];            }        }        if(j<n2){            for(i=j;i<n2;i++,k++){                array[k] = R[i];            }        }        return count;    }}
1 0