歸併排序-陣列中的逆序對
參考《劍指Offer》
題目:
在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個陣列,求出這個陣列中的逆序對的總數。
輸入:
每個測試案例包括兩行:
第一行包含一個整數n,表示陣列中的元素個數。其中1 <= n <= 10^5。
第二行包含n個整數,每個陣列均為int型別。
輸出:
對應每個測試案例,輸出一個整數,表示陣列中的逆序對的總數。
樣例輸入:
4
7 5 6 4
樣例輸出:
5
解析
1、我們一開始想到的一般就是順序掃描整個陣列,每掃描一個數字,就諸葛比較該數字與它後面的數字的大小,但是這個複雜度是O(n*n),應當存在更快的演算法。然後發現歸併演算法在此就可以使用。
2、歸併演算法的思路就是分治,先兩個兩個排序,然後四個四個排序,一直到排完為止。
3、在這道題使用歸併的思想就是在排序的同時進行逆序對的判斷。
兩個兩個排序的時候,我們判斷前一個數是否大於後一個數,如果是,那麼就存在一個逆序對。
於是當四個四個排序的時候,我們只需要判斷前兩個數中是否有數大於後兩個數,如果存在一個那麼就是存在一個逆序對,如果存在2*2個,那麼就存在2*2個逆序對。而前兩個本身就不需要進行比較了,因為已經排好序了。
程式碼
#include <stdio.h>
int n, arr[5000], tmp[5000];
//歸併排序,過程中 統計逆序數
int merge(int start, int mid, int end)
{
int cnt = 0;
int i = start;
int j = mid+1;
int k = start;
while( i<=mid && j<= end)
{
if(arr[i] > arr[j])
{
tmp[k++] = arr[i++];
//由於是從大到小排序,並且arr[i] > arr[j]
//所以arr[i]與arr[j]右邊的每一個陣列成的都是逆序對
cnt += (end-j+1);
}
else
{
tmp[k++] = arr[j++];
}
}
while(i<=mid)
tmp[k++] = arr[i++];
while(j<=end)
tmp[k++] = arr[j++];
for(int i=start; i<=end; i++)
arr[i] = tmp[i];
return cnt;
}
int inversePairs(int start, int end)
{
int cnt = 0;
if(start < end)//僅僅需要判斷1個以上的數
{
int mid = (start + end)/2;
cnt += inversePairs(start, mid); //左半部分 逆序對數量
cnt += inversePairs(mid+1, end); //右半部分
cnt += merge(start, mid, end); //合併兩部分,並計算數量
}
return cnt;
}
int main()
{
while( scanf("%d", &n) != EOF)
{
for(int i=0; i<n; i++)
scanf("%d", &arr[i]);
printf("%d\n",inversePairs(0, n-1));
}
return 0;
}
相關文章
- 歸併排序思想應用之----求陣列中的逆序對排序陣列
- 逆序對的數量(歸併排序模板)排序
- 歸併排序的經典-求逆序對排序
- LeetCode C++ 劍指 Offer 51. 陣列中的逆序對【歸併排序/樹狀陣列/線段樹】LeetCodeC++陣列排序
- 陣列中的逆序對陣列
- HDU 2689 【歸併排序求逆序對】排序
- 歸併排序求逆序數排序
- 進階指南--超快速排序(歸併+逆序對)排序
- 【劍指offer】陣列中的逆序對陣列
- JZ-035-陣列中的逆序對陣列
- 左神基礎班02、陣列中的逆序對陣列
- 劍指Offer-37-陣列中逆序對陣列
- 樹狀陣列和逆序對陣列
- 劍指offer——陣列中的逆序對C++(75%)陣列C++
- HDU 4911 Inversion(歸併排序求逆序數)排序
- 歸併排序:陣列和連結串列的多種實現排序陣列
- JZOJ 3.10 1542——跑步(樹狀陣列+模擬+排序/歸併排序)陣列排序
- LeetCode 493. 翻轉對(歸併排序 || 離散化+樹狀陣列)LeetCode排序陣列
- 陣列元素逆序陣列
- 歸併排序 nO(lgn) 稽核中排序
- 藍橋杯 小朋友排隊 (歸併排序 逆序數 好題)排序
- [排序] 歸併排序排序
- 2個有序陣列,歸併重拍陣列
- 7-1將陣列中的數逆序存放陣列
- 歸併排序排序
- 演算法合併排序陣列演算法排序陣列
- 快速排序&&歸併排序排序
- HDU 2689 Sort it【樹狀陣列求逆序對】陣列
- Javascript中的陣列物件排序JavaScript陣列物件排序
- 分治法演算法學習(一)——歸併排序、求最大子陣列和演算法排序陣列
- 歸併排序與快速排序的簡明實現及對比排序
- 四、歸併排序 && 快速排序排序
- java歸併排序Java排序
- [java]歸併排序Java排序
- 歸併排序模板排序
- 陣列的排序陣列排序
- 歸併排序--二路排序排序
- 排序演算法__歸併排序排序演算法