數組中的逆序對

在牛客網上看到這樣一道題:

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

輸入描述:

題目保證輸入的數組中沒有的相同的數字

數據範圍:

對於%50的數據,size<=10^4

對於%75的數據,size<=10^5

對於%100的數據,size<=2*10^5

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

解題思路:
最簡單的辦法就是遍歷每一個元素,讓其與後面的元素對比,如果大於則計數器加一,時間複雜度爲o(n^2),必然超時。
      其實這道題考查的是歸併排序的思想,求逆序對的過程就是一個求歸併排序的過程,時間複雜度爲o(nlogn)。
      總體的思想就是把數組分成兩段,求段內的逆序對數:
count += InversePairsCore(arr,left,mid,tempArr)
count +=InversePairsCore(arr,mid+1,end,tempArr)
      然後再求段間的逆序對數:
count += Merge(arr,left,mid,end,tempArr)
      Merge:
再求段間逆序對的時候,我們分爲arr[start->mid]和arr[mid+1->end],設置兩個指針ij分別指向兩段數組的末尾元素,
即i = mid, j = end,然後比較arr[i]和arr[j]。
如果arr[i]>arr[j],因爲兩段數組都是有序的,所以arr[i]>arr[mid+1->end], 逆序對數爲j-(mid+1)+1,將arr[i]放入tempArr中,
i往前移動。
果arr[i]<arr[j],則將arr[j]放入tempArr中,j往前移動

因爲最近在學習node,所以練習算法的時候也用node來寫,和c++這種語言相比,node這種動態語言寫算法時還是有些不方便的地方的。。。。貼上代碼:

function InversePairs(data)
{
    // write code here
    var tempArr = new Array(data.length);
    var count = InversePairsCore(data,0,data.length-1,tempArr);
    return count%1000000007;
}

function Merge(arr,start,mid,end,tempArr){
    var i = mid, j = end, count = 0, k = 0;
    
    while(i >= start && j > mid){
        if(arr[i] > arr[j]){
            count += (j-mid);
            tempArr[k++] = arr[i--];
        }else{
            tempArr[k++] = arr[j--];
        }
    }
    while(i >= start){
        tempArr[k++] = arr[i--];
    }
    while(j > mid){
        tempArr[k++] = arr[j--];
    }

    for(var l = 0;l < k;l++){
        arr[end-l] = tempArr[l]
    }
    return count%1000000007 ;
}
    
function InversePairsCore(arr, start, end, tempArr){
    var count = 0;
    if(start < end){
        var mid = Math.floor((end + start)/2);
        count += InversePairsCore(arr,start,mid,tempArr);
        count += InversePairsCore(arr,mid+1,end,tempArr);
        count += Merge(arr,start,mid,end,tempArr);
        
    }
    return count%1000000007 ;
}
    
module.exports = {
    InversePairs : InversePairs
};


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