重複する要素がない配列内の逆ペアの数を見つけます

問題:

繰り返される要素のないシーケンスa [n]が与えられた場合、次の条件を満たすペア(i、j)がいくつ存在するかを尋ねます。 0<=i<j<n && a[i] > a[j]

解決策:マージソート

シーケンスの逆対数=左半分の逆対数+右半分の逆対数+マージプロセス中に左半分の要素の前に配置された右半分の要素の数

T(n)= 2 T(n 2)+ O(n)T(n)= 2T(\ frac {n} {2})+ O(n) T n =2 T 2n個+O n
なので、時間計算量はO(nlogn)です。

//合并a[0, n1)与a[n1, n),返回合并中发现的逆序对数
int mergeArray(int a[], int n1, int n){
    
    
    int ans=0, p=0, q=n1;
    int *b = new int[n];
    memcpy(b, a, n*sizeof(int));
    for(int i=0; i<n; i++){
    
    
        //fill in a[i]
        if(q>=n || (p<n1 && b[p]<b[q])){
    
    
            //取前一半的数填,此时后半边已经填入了q-n1个,都和此数构成逆序对
            a[i] = b[p++];
            ans += q - n1;
        }
        else a[i] = b[q++];
    }
    delete[] b;
    return ans;
}

//返回a[0, n)中的逆序对数,同时把a归并排序
int mergeSort(int a[], int n){
    
    
    if(n==1) return 0;
    int mid = n/2;
    return mergeSort(a, mid) + mergeSort(a+mid, n-mid) + mergeArray(a, mid, n);
}

おすすめ

転載: blog.csdn.net/sinat_37517996/article/details/105780315