在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。
即,在陣列中,若0=a[j],就說明這兩個數是逆序對,乙個陣列中逆序對數量就是逆序數。
第一種思路:用兩個for迴圈解決,用第乙個迴圈i從陣列開頭開始,另乙個迴圈j從i+1開始,即此時滿足了,ia[j],那就逆序數+1.
這種方法的是時間複雜度是o(n^2),n為陣列的長度。若當n=100000的時候,就會超時。
所以這種方法的缺陷就是時間複雜度過大,下面提出另一種思路。
第二種思路:歸併排序原理講解及c++實現)
1)將陣列分成兩部分,分別求出左半邊逆序數和右半邊的逆序數
2)再計算有多少逆序是由左半邊取乙個數和右半邊取乙個數構成的
其中,第二小步的關鍵:左半邊和右半邊要排好序(因為是找前面比後面大的,所以一般從大到小排)。
這種方法的時間複雜度是o(nlogn),比第一種方法的時間複雜度要低。
綜上所述,所以一般使用第二種,歸併排序的思想來做,防止超時。
#include#includeusing namespace std;
int a[100010];
int b[100010];
void merge(int a,int s,int m,int e,int b)
while(p1<=m)
b[pb++] = a[p1++];
while(p2<=e)
b[pb++] = a[p2++];
for(int i = 0;i < e-s+1;i++)
a[s+i] = b[i]; }
long long count(int a,int s,int m,int e)
else
p2++; }
return res; }
long long mergesort_res(int a,int s,int e,int b)
return res;
}int main()
求序列逆序數
由1,2,n 組成的乙個有序陣列稱為乙個n級排列。在乙個排列中如果一對數的前後位置與大小順 序相反,即大數排在小數的前面,則稱它們為乙個逆序。乙個排列中所有逆序的總和稱為該排列的逆序數。那麼,如何求解乙個序列的逆序數呢?暴力法是問題解的最簡單的方法,下面給出核心 int inversionnumbe...
求序列逆序數
求序列逆序數 整體思路是用到分治的思想,其實該問題可以在歸併排序過程中解決,因此該題 只需要在歸併排序 上增加乙個變數記錄逆序數即可,但正如那個修機器的故事一樣,換釘子不難,但知道在 換釘子卻是非常關鍵。如下,只是在歸併排序的基礎上增加了乙個記錄逆序數的地方 void reverse int num...
分治法求整數序列的逆序數
在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個 逆序。乙個排列中逆序的總數就稱為這個排列的 逆序數。求逆序數的方法很多。最容易想到的辦法是分別對序列中每乙個元素求其逆序數,再求所有元素的逆序數總和,易分析得出這樣的方法其時間複雜度為o n2 這裡介紹一種...