面試題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複雜度的算法不就能夠了嗎,那不就是歸併排序嗎!spa

固然,須要O(n)的額外空間,時間複雜度爲O(logn)code

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;
    }
};
相關文章
相關標籤/搜索