關於數組中的逆序對

來源:互聯網
上載者:User

題目描述:

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

輸入:

每個測試案例包括兩行:

第一行包含一個整數n,表示數組中的元素個數。其中1 <= n <= 10^5。

第二行包含n個整數,每個數組均為int類型。

輸出:

對應每個測試案例,輸出一個整數,表示數組中的逆序對的總數。

範例輸入:

4

7 5 6 4

範例輸出:

5

思路:最簡單的方法是順序數組,將每個數字與後面的比較,統計逆序對的個數,這種方法的時間複雜度為O(n*n),這種方法寫出的代碼在九度OJ上測試,會逾時。劍指offer給出了歸併排序的思路,這個有點難想到啊,也可能是我太弱了,根本沒往這方面想!理解了思路,就不難了,將數組劃分成兩個子數組,再將子數組分別劃分成兩個子數組,統計每個子數組內的逆序對個數,並將其歸併排序,再統計兩個子數組之間的逆序對個數,並進行歸併排序。這就是歸併排序的變種,在歸併排序代碼的基礎上稍作改進即可。

合理還要注意一點:全域變數count不能聲明為int型,必須為long long型。因為題目中說數組最大為10^5,那麼最大逆序對為(10^5-1)*10^5/2,這個數大約在50億左右,超過了int型的表示範圍。

AC代碼如下:

#include<stdio.h>  #include<stdlib.h>        /* 統計兩個子數組之間的逆序對 */long long MergePairsBetweenArray(int *arr,int *brr,int start,int mid,int end)  {      int i = mid;      int j = end;      int k = end;  //輔助數組的最後一位      long long count = 0;            //設定兩個指標i,j分別從右往左依次比較,      //將較大的依次放入輔助數組的右邊      while(i>=start && j>=mid+1)      {          if(arr[i] > arr[j])          {              count += j-mid;              brr[k--] = arr[i--];          }          else            brr[k--] = arr[j--];      }            //將其中一個數組中還剩下的元素拷貝到輔助數組中,      //兩個迴圈只會執行其中的一個      while(i>=start)          brr[k--] = arr[i--];      while(j>=mid+1)          brr[k--] = arr[j--];            //從輔助數組中將元素拷貝到原數組中,使其有序排列      for(i=end;i>k;i--)          arr[i] = brr[i];            return count;  }        /* 統計數組中的所有的逆序對返回欄目頁:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/*/long long CountMergePairs(int *arr,int *brr,int start,int end)  {      long long PairsNum = 0;      if(start<end)      {          int mid = (start+end)>>1;          PairsNum += CountMergePairs(arr,brr,start,mid); //統計左邊子數組的逆序對          PairsNum += CountMergePairs(arr,brr,mid+1,end); //統計右邊子數組的逆序對          PairsNum += MergePairsBetweenArray(arr,brr,start,mid,end); //統計左右子數組間的逆序對      }      return PairsNum;  }        /* 將函數封裝起來 */long long CountTotalPairs(int *arr,int len)  {      if(arr==NULL || len<2)          return 0;            int *brr = (int *)malloc(len*sizeof(int));      if(brr == NULL)          exit(EXIT_FAILURE);            long long sum = CountMergePairs(arr,brr,0,len-1);      free(brr);      brr = NULL;            return sum;  }        int main()  {      int n;      while(scanf("%d",&n) != EOF)      {          int *arr = (int *)malloc(n*sizeof(int));          if(arr == NULL)              exit(EXIT_FAILURE);                int i;          for(i=0;i<n;i++)              scanf("%d",arr+i);                printf("%lld\n",CountTotalPairs(arr,n));                free(arr);          arr = NULL;      }      return 0;  }

出處:http://blog.csdn.net/ns_code/article/details/27520535

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.