每日一题--数组中的逆序对

来源:互联网 发布:yaf 数据库 yii 编辑:程序博客网 时间:2024/05/20 07:15

解题思路:拿数组中的每个数组元素跟它后面的比较,时间复杂度为O(n^2)
实际统计逆序对的过程:先把数组分割成子数组,先统计出子数组内部的逆序对数目,然后再统计出两个相邻子数组之间的逆序对数目,在统计的过程中还要进行排序(以免进行重复计算),这个排序过程实际上是归并排序(分治策略)。时间复杂度是O(nlogn)。
代码

/**问题描述:在数组中两个数字如果前面的一个数字比后面的一个数字大则为一个逆序对。 * 输入一个数组,求这个数组中逆序对的数目 * 输入:{7,5,6,4} * 输出:5 * Created by lxq on 2017/9/10. */public class Problem {    public int inversePairs(int[] array){        if(array==null)            return 0;        int[] copy = array.clone();        return mergeSort(array,copy,0,array.length-1);    }    private int mergeSort(int[] array, int[] result, int start, int end) {        if(start==end){            result[start] =array[start];            return 0;        }        int length = (end-start)/2;        //最后得到的是一个前半段和后半段都分别排序的数组array        int left = mergeSort(result,array,start,start+length); //左边数目        int right = mergeSort(result,array,start+length+1,end);//右边数目        //两个相邻子数组之间的逆序对        int leftIndex = start+length; //前半段的最后一个数字的下标        int rightIndex = end;         //后半段最后一个数字的下标        int count = 0;        int point = rightIndex;     //最终排好序的数组的指针        //两个指针分别向前移动        while(leftIndex>=start&&rightIndex>=start+length+1){            if(array[leftIndex]>array[rightIndex]){                result[point--] = array[leftIndex--];                count += rightIndex-start-length;//右边数组中剩余的都比左边指针的小,因为都排好序了            }else {                result[point--] = array[rightIndex--];            }        }        //如果最后只剩下左边的数组的一部分        for(int i=leftIndex;i>=start;i++)            result[point--] = array[i];        for(int j = rightIndex;j>=start+length+1;j++)            result[point--] = array[j];       return left+right+count;    }}
原创粉丝点击