数组中的逆序对

来源:互联网 发布:北京小学生id软件下载 编辑:程序博客网 时间:2024/06/06 12:52
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 
输入描述:

题目保证输入的数组中没有的相同的数字

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

对于%100的数据,size<=2*10^5



输入例子:
1,2,3,4,5,6,7,0

输出例子:

7

/*归并排序的改进,把数据分成前后两个数组(递归分到每个数组仅有一个数据项),
合并数组,合并时,出现前面的数组值array[i]大于后面数组值array[j]时;则前面
数组array[i]~array[mid]都是大于array[j]的,count += mid+1 - i
参考剑指Offer,但是感觉剑指Offer归并过程少了一步拷贝过程。
还有就是测试用例输出结果比较大,对每次返回的count mod(1000000007)求余
*/
 
publicclass Solution {
    publicint InversePairs(int[] array) {
        if(array==null||array.length==0)
        {
            return0;
        }
        int[] copy = newint[array.length];
        for(inti=0;i<array.length;i++)
        {
            copy[i] = array[i];
        }
        intcount = InversePairsCore(array,copy,0,array.length-1);//数值过大求余
        returncount;
         
    }
    privateint InversePairsCore(int[] array,int[] copy,intlow,inthigh)
    {
        if(low==high)
        {
            return0;
        }
        intmid = (low+high)>>1;
        intleftCount = InversePairsCore(array,copy,low,mid)%1000000007;
        intrightCount = InversePairsCore(array,copy,mid+1,high)%1000000007;
        intcount = 0;
        inti=mid;
        intj=high;
        intlocCopy = high;
        while(i>=low&&j>mid)
        {
            if(array[i]>array[j])
            {
                count += j-mid;
                copy[locCopy--] = array[i--];
                if(count>=1000000007)//数值过大求余
                {
                    count%=1000000007;
                }
            }
            else
            {
                copy[locCopy--] = array[j--];
            }
        }
        for(;i>=low;i--)
        {
            copy[locCopy--]=array[i];
        }
        for(;j>mid;j--)
        {
            copy[locCopy--]=array[j];
        }
        for(ints=low;s<=high;s++)
        {
            array[s] = copy[s];
        }
        return(leftCount+rightCount+count)%1000000007;
    }
}

参考《剑指offer》用归并排序的思想, 时间复杂度O(nlogn)

代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
intInversePairs(vector<int> data) {
        intlength  = data.size();
        returnmergeSort(data, 0, length-1);
    }
 
    intmergeSort(vector<int>& data, intstart, intend) {
        // 递归终止条件
        if(start >= end) {
            return0;
        }
 
        // 递归
        intmid = (start + end) / 2;
        intleftCounts = mergeSort(data, start, mid);
        intrightCounts = mergeSort(data, mid+1, end);
 
        // 归并排序,并计算本次逆序对数
        vector<int> copy(data); // 数组副本,用于归并排序
        intforeIdx = mid;      // 前半部分的指标
        intbackIdx = end;      // 后半部分的指标
        intcounts = 0;         // 记录本次逆序对数
        intidxCopy = end;      // 辅助数组的下标
        while(foreIdx>=start && backIdx >= mid+1) {
            if(data[foreIdx] > data[backIdx]) {
                copy[idxCopy--] = data[foreIdx--];
                counts += backIdx - mid;
            else{
                copy[idxCopy--] = data[backIdx--];
            }
        }
        while(foreIdx >= start) {
            copy[idxCopy--] = data[foreIdx--];
        }
        while(backIdx >= mid+1) {
            copy[idxCopy--] = data[backIdx--];
        }
        for(inti=start; i<=end; i++) {
            data[i] = copy[i];
        }
 
        return(leftCounts+rightCounts+counts);
    }


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 征服护士妈全文目录34章 迷糊故意穿超短裙坐公交 大妈咪女教师全集 雪白短裙教师妈咪风雨夜 母亲轮陷公交 客厅弄醒穿花裙子午睡的妈 沙发午睡花裙子在线资源 公交上的妈咪 儿子你要高就快点你国语 花裙子母亲午睡 儿子你不能这样啊国语高清 被要求穿超级短的超短裙 穿花裙子躺在沙发上 客厅弄醒午睡的妈连接 家庭毋HH伦s线视频中字 客厅弄硬午睡的儿子短文 客厅搞午睡的母亲 弄醒客厅午睡的母亲在线播放 弄醒午睡的妈视频连接 在客厅睡的午的母亲电影 客厅午睡的母亲在线下载 韩国午睡弄醒午睡的妈 在客厅弄醒午睡的 客厅午睡的母亲穿裙子在线播放 客厅午睡的母亲自拍 客厅里硬搞午睡的母亲视频 对白搞硬沙发午睡的儿子 客厅沙发儿子碎花裙 电影客厅午睡的母亲 客厅午睡以为你是爸爸 客厅弄醒午唾的儿子 客厅搞硬午睡的儿子小说 客厅弄醒穿花裙子午睡的妈电影 在客厅里弄醒午睡的儿子 中午弄醒正在午睡中的护校小 客厅弄醒午睡的妈视频完整迅雷 弄醒客厅午睡花裙子母亲 对白弄醒午睡的儿子 客厅沙发午睡的妈 母亲今晚让你入个够 在客厅里弄醒午睡的