刷題-數組中逆序對數目

問題描述:

在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007

輸入:1,2,3,4,5,6,7,0,輸出:7.

解題思路:

思路1:暴力搜索

暴力搜索的方法思路很簡單,就是從數組第一個數據開始遍歷,逐個比較這個數據與其後數據的大小,記錄逆序個數,該方法的時間複雜度爲O(n^2)。

思路2:分析/歸併排序思想

1、基於分治思想的歸併排序:

給定一個無序數組,歸併排序的思路如下圖所示:

                                                                                      

將數組分成兩個長度相同的子數組,再將每個子數組分成兩個長度相同的子數組,直到不能分裂後,歸併排序將相鄰的兩個子數組結合並排序,最後得到一個有序的。

2、統計逆序對數目:

class Solution {
public:
    int InversePairs(vector<int> data) {
       int length=data.size();
        if(length<=0)
            return 0;
       vector<int> copy; //排序的輔助數組
       for(int i=0;i<length;i++)
           copy.push_back(data[i]);
       long long count=InversePairsCore(data,copy,0,length-1);
       return count%1000000007;
    }
    long long InversePairsCore(vector<int> &data,vector<int> &copy,int start,int end){
        //指向相同元素,沒有逆序,也就到了對並排序中最底層,
        if(start==end){
           copy[start]=data[start];
           return 0; //沒有逆序對,返回0。
        }
        int length=(end-start)/2; //分裂
        // 使data左半段有序,並返回左半段逆序對的數目
        long long left=InversePairsCore(copy,data,start,start+length);
        // 使data右半段有序,並返回右半段逆序對的數目
        long long right=InversePairsCore(copy,data,start+length+1,end); 
        //對data左半段和右半段的數據進行歸併排序,並統計逆序個數
        int i=start+length;
        int j=end;
        int indexcopy=end;
        long long count=0;
        //歸併排序,同時統計逆序對數
        while(i>=start&&j>=start+length+1){
            if(data[i]>data[j]){
                copy[indexcopy--]=data[i--];
                //統計歸併的兩個數組逆序對數
                count=count+j-start-length;//count=count+j-(start+length+1)+1;
            }
            else{
                copy[indexcopy--]=data[j--];
            }
        }
        for(;i>=start;i--)
            copy[indexcopy--]=data[i];
        for(;j>=start+length+1;j--)
            copy[indexcopy--]=data[j];
        //data總的逆序對數:左半段內部逆序對數+右半段內部逆序對數+左右兩段間的逆序對數
        return left+right+count;
    }
};

 

                   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章