(劍指Offer)面試題36:數組中的逆序對

來源:互聯網
上載者:User

標籤:

題目:

在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。

思路:

1、順序掃描

順序掃描整個數組,每掃描到一個數字,就將該數字跟後面的數字比較,如果大於的話,則這兩個數字構成了逆序對。(比較簡單,這裡就不貼出代碼)

時間複雜度:O(n^2)

2、歸併思想

將數組不斷地等分為兩個子數組,然後自下而上地統計兩個子數組各自的逆序對以及合并後的逆序對。

假設兩個子數組左右分別為A,B,長度分為lenA,lenB,子數組已排好序,那麼如何計算逆序對的個數呢?

當pA=lenA-1;pB=lenB-1;A[pA]>A[pB],說明A的最後一個數比B所有的數都大,此時個數為lenB,pA--;如果A[pA]<B[pB],說明左邊的數不一定比右邊的大,pB--;依次計算直至pA或pB為0,這樣就得到了兩個數組合并時的逆序對,再加上左子數組的逆序對和右子數組的逆序對,就等於整個數組的逆序對。

(代碼中巧妙地利用了一個輔助數組來排序,參考下面的代碼)

時間複雜度:O(nlogn)

代碼:
#include <iostream>using namespace std;int InversePairsCore(int *data,int *copy,int start,int end){    if(start==end){        copy[start]=data[start];        return 0;    }    int length=(end-start)>>1;    int left=InversePairsCore(copy,data,start,start+length);    int right=InversePairsCore(copy,data,start+length+1,end);    int i=start+length;    int j=end;    int copyIndex=end;    int count=0;    while(i>=start && j>=start+length+1){        if(data[i]>data[j]){            copy[copyIndex]=data[i];            copyIndex--;            i--;            count+=j-(start+length);        }        else{            copy[copyIndex]=data[j];            copyIndex--;            j--;        }    }    for(;i>=start;i--)        copy[copyIndex--]=data[i];    for(;j>=start+length+1;j--)        copy[copyIndex--]=data[j];    return left+right+count;}int InversePairs(int *data,int 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 main(){    int A[]={7,5,6,4};    int length=sizeof(A)/sizeof(A[0]);    cout << InversePairs(A,length) << endl;    return 0;}
線上測試OJ:

http://www.nowcoder.com/books/coding-interviews/96bd6684e04a44eb80e6a68efc0ec6c5?rp=2

AC代碼:

class Solution {public:    int InversePairs(vector<int> data) {        int length=data.size();        if(length<=1)            return 0;        int start=0;        int end=length-1;        int result=InversePairsCore(data,start,end);        return result;    }        int InversePairsCore(vector<int> &data,int start,int end){        if(start>=end)            return 0;        int mid=start+((end-start)>>1);        int left=InversePairsCore(data,start,mid);        int right=InversePairsCore(data,mid+1,end);                int i=start;        int j=mid+1;        int count=0;        vector<int> tmp;        while(i<=mid && j<=end){            if(data[i]>data[j]){                count+=end-j+1;                tmp.push_back(data[i]);                i++;            }            else{                tmp.push_back(data[j]);                j++;            }        }               while(i<=mid)            tmp.push_back(data[i++]);        while(j<=end)            tmp.push_back(data[j++]);               for(int k=start;k<=end;k++)            data[k]=tmp[k-start];                return left+count+right;    }};

 

class Solution {public:    int InversePairs(vector<int> data) {        int length=data.size();        if(length<=0)            return 0;        vector<int> copy(data.begin(),data.end());        int start=0;        int end=length-1;        int count=InversePairsCore(data,copy,start,end);        return count;    }        int InversePairsCore(vector<int> &data,vector<int> &copy,int start,int end){        if(start==end){            copy[start]=data[start];            return 0;        }        int length=(end-start)>>1;        int left=InversePairsCore(copy,data,start,start+length);        int right=InversePairsCore(copy,data,start+length+1,end);                int i=start+length;        int j=end;        int copyIndex=end;        int count=0;        while(i>=start && j>=start+length+1){            if(data[i]>data[j]){                copy[copyIndex--]=data[i--];                count+=j-(start+length);            }            else                copy[copyIndex--]=data[j--];        }                for(;i>=start;i--)            copy[copyIndex--]=data[i];        for(;j>=start+length+1;j--)            copy[copyIndex--]=data[j];                return left+count+right;    }};

(劍指Offer)面試題36:數組中的逆序對

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.