[剑指offer]51-数组中的逆序对(归并排序)

Posted coding-gaga

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[剑指offer]51-数组中的逆序对(归并排序)相关的知识,希望对你有一定的参考价值。

题目链接

https://www.nowcoder.com/questionTerminal/96bd6684e04a44eb80e6a68efc0ec6c5

题意

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007。题目保证输入的数组中没有的相同的数字。

解题思路

在归并排序的过程中计逆序对。时间复杂度O(nlogn),空间复杂度O(n)。

  • 将数组从中间分成前后两个数组(递归到只有一个数据项)
  • 然后合并并排序两个数组,排序结果在copy数组。具体地,i、j指针从两个数组后向前遍历,将大的拷贝到copy数组(copy数组从后往前填)。最后剩下的数组的剩下的部分一并拷贝到copy数组
  • 在合并过程中计逆序对,若i指向的元素大于j,则count+=j-mid;即mid+1到j的元素都比i指向的元素小。
  • 最终返回的count是两个数组内部的逆序对 + 合并过程中的逆序对数(即上一条)。

注意

  • 每次递归传参copy和array换位置,保证第一个参数的数组是内部有序的,第二个参数的数组是下一次拷贝的存储位置。(滚动数组)。
  • size_t 是>=0 所以当i=0,i--,i会等于一个较大正数而不是-1,仍满足while(i>=l),使得程序错误。
  • cnt+=(j-mid)%1000000007应改为cnt=(cnt+(j-mid))%1000000007

代码

class Solution {
public:
    int InversePairs(vector<int> data) {
        int cnt=0;
        if(!data.empty()){
            vector<int> copy;
            for(auto it=data.begin();it!=data.end();++it){
                copy.push_back(*it);
            }
            cnt=inversePairCnt(data,copy,0,data.size()-1);
        }
        return cnt;
    }
private:
    int inversePairCnt(vector<int>& data,vector<int>& copy,int l,int r){
        if(l==r){
            return 0;
        }
        int mid=(l+r)>>1;
        int leftCnt=inversePairCnt(copy,data,l,mid);
        int rightCnt=inversePairCnt(copy,data,mid+1,r);
        
        int i=mid;
        int j=r;
        int copyIndex=r;
        int cnt=0;
        while(i>=l&&j>mid){
            if(data[j]>data[i]){
                copy[copyIndex--]=data[j--];
            }
            else{
                cnt=(cnt+(j-mid))%1000000007;//
                copy[copyIndex--]=data[i--];
            }
        }
        while(i>=l){//
            copy[copyIndex--]=data[i--];
        }
        while(j>mid){
            copy[copyIndex--]=data[j--];
        }
        return (leftCnt+rightCnt+cnt)%1000000007;
    }
};

以上是关于[剑指offer]51-数组中的逆序对(归并排序)的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer 51. 数组中的逆序对(归并排序,Java)

归并排序应用——剑指 Offer 51. 数组中的逆序对

结合《剑指offer(第二版)》面试题51来谈谈归并排序

剑指 Offer 51. 数组中的逆序对

剑指Offer对答如流系列 - 数组中的逆序对

Java 剑指offer(51)数组中的逆序对