題目描述:
在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。
輸入:
每個測試案例包括兩行:
第一行包含一個整數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