求數組中的逆序對(來源於劍指名企offer)


思路:

利用歸併排序的思想,一邊歸併排序,一邊求逆序對。時間複雜度爲O(n log n)

步驟:遞歸實現

(1)現將數組拆分成2兩部分,統計出子數組內部的逆序對left、right;

(2)然後再統計出兩個相鄰子數組之間的逆序對count。在統計過程中,對數組進行排序。(歸併過程)

(3)最終的逆序對個數=left+right+count;


int inversePairs( int *data, in length)
{
     if(data==NULL  ||  length<0)
        return 0;
     int *copy=new int[length];
     for(int i=0;i<length;i++)
         copy[i]=data[i];

     int count=inversePairsCore(data, copy, 0, length-1);
     
     delete [] copy;
     return count;
} 

int inverseParisCore(int *data, int *copy, start, end)
{
    //遞歸出口
    if(start==end)
    {
        copy[start]=data[start];
        return 0;
    }

    int length=(end-start)/2;
    int left=inversePairsCore(data, copy, start, start+length);//遞歸調用
    int right=inversePairsCore(data, copy, start+length+1, end);//遞歸調用

    //歸併排序,且求左右子數組間逆序對
    int i=start+length;//指向左子數組的最後位置
    int j=end;         //指向右子數組的最後位置
    int indexCopy=end;
    int count=0;

    while(i>=start && j>=start+length+1)
    {
        if( data[i]> data[j] )
        {
            copy[indexCopy--]=data[i--];
            count+= ( j-(start+length+1)+1 );
        }
        else
            copy[indexCopy--]=data[j--];
    }

   //拷貝剩餘數組部分
    for(; i>=0; i--)
       copy[indexCopy--]=data[i];
    for(; j>=start+length+1; j--)
       copy[indexCopy--]= data[j];

     return count+left+right;
}
  





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