<leetcode c++>面试题51. 数组中的逆序对

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

很容易想到从后往前折半插入排序时顺便记录比当前数小得数,但是这种方法在用例30的时候就超时了。。

class Solution {
public:
    int count(vector<int>& nums, int pivot, int st, int ed){
        int l=st,r=ed;
        if(nums[pivot]<=nums[st])return 0;
        if(nums[pivot]>nums[ed]){
            int tmp=nums[pivot];
            for(int i=st;i<=ed;i++){
                nums[i-1]=nums[i];
            }
            nums[ed]=tmp;
            return ed-st+1;
        }
        while(l<r){
            int mid=l+(r-l)/2;
            if(nums[mid]>=nums[pivot])
                r=mid;
            else
                l=mid+1;
        }
        int tmp=nums[pivot];
        for(int i=st;i<l;i++){
            nums[i-1]=nums[i];
        }
        nums[l-1]=tmp;
        return l-st;
    }
    int reversePairs(vector<int>& nums) {
        //从后往前折半插入排序
        int n=nums.size();
        int res=0;
        for(int i=n-2;i>=0;i--){
            res+=count(nums,i,i+1,n-1);
        }
        return res;
    }
};

然后我就思考毕竟插入排序要移动数组元素,最后的总体时间复杂度是O(n^2),那么找到一个插入和比较都是logn复杂度的算法不就可以了吗,那不就是归并排序吗!

当然,需要O(n)的额外空间,时间复杂度为O(logn)

class Solution {
public:
    int res=0;

    void merge(vector<int>& nums, int left, int mid, int right){
        vector<int> tmp(right-left+1,0);
        int l1=left,l2=mid+1,l3=0;
        while(l1<=mid&&l2<=right){
            if(nums[l1]<=nums[l2]){
                tmp[l3++]=nums[l1++];
                res+=(l2-mid-1);
            }
            else
                tmp[l3++]=nums[l2++];
        }
        while(l1<=mid){
            tmp[l3++]=nums[l1++];
            res+=(l2-mid-1);
        }
        while(l2<=right)tmp[l3++]=nums[l2++];
        for(int i=left;i<=right;i++){
            nums[i]=tmp[i-left];
        }
    }

    void mergeSort(vector<int>& nums, int left, int right){
        if(left<right){
            int mid = left+(right-left)/2;
            mergeSort(nums,left,mid);
            mergeSort(nums,mid+1,right);
            merge(nums,left,mid,right);
        }
    }
        
    int reversePairs(vector<int>& nums) {
        //归并排序
        int n=nums.size();
        mergeSort(nums,0,n-1);
        return res;
    }
};

 

posted @ 2020-04-24 22:08  鳄鱼四驱车  阅读(136)  评论(0编辑  收藏  举报