分治法求乙個N個元素陣列的逆序數

2022-04-09 02:52:07 字數 1153 閱讀 8158

背景

逆序數:也就是說,對於n個不同的元素,先規定各元素之間有乙個標準次序(例如n個 不同的自然數,可規定從小到大為標準次序),於是在這n個元素的任一排列中,當某兩個元素的先後次序與標準次序不同時,就說有1個逆序。乙個排列中所有逆序總數叫做這個排列的逆序數。

定義在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。逆序數為偶數的排列稱為偶排列;逆序數為奇數的排列稱為奇排列。如2431中,21,43,41,31是逆序,逆序數是4,為偶排列。

問題求解

分治法求逆序數相當於在歸併排序的過程中加上相應的逆序數的數目。

假設陣列a被劃分成前半部分(a[left]->a[mid]),後半部分(a[mid+1],a[right])

假設前半部分與後半部分各自都是從小到大排好序的,若a[left]

使用分治法解決該問題的時間複雜度為o(n*log(n)).

**如下:

1 #include

2 #include

3 using namespace std;

4 int merge(int *a,int left,int mid,int right)

17 else

22 index++;

23 }

24 //i=mid的時候,a[i]位置的數還未填充到陣列temp中

25 //因此判斷條件包含等於號

26 if(i<=mid)

27 for(;i<=mid;i++)

32 if(j<=right)

33 for(;j=right)

47 return 0;

48 int mid=(left+right)/2;

49 int num1=inversion(a,left,mid);

50 int num2=inversion(a,mid+1,right);

51 return num1+num2+merge(a,left,mid,right);

54 }

55 int main()

56 ;

58 cout<

求N個元素的逆序數

求n個元素的逆序數 解法一 窮舉,時間複雜度為o n2 解法二 使用歸併排序計算逆序數,時間複雜度o n lngn 使用分治思想,以mid值將序列分為左序列 left mid 右序列 mid 1 right 將左右子串行排序好之後,進行合併。合併時獲得逆序數,因為左序列已經保證有序,當右序列的值小於...

乙個快速法求素數的程式

閒暇時寫了乙個找出小於某個數字的素數的程式。最常見的方法是篩選法吧。原理大致如下 若要求得16以內的所有素數,1 在陣列中存放一下資料 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 2 先篩選掉是2的倍數 2 3 4 5 6 7 8 9 10 11 12 13 14 15...

乙個陣列有 N 個元素,求連續子陣列的最大和

輸入描述 輸入為兩行。第一行乙個整數n 1 n 100000 表示一共有n個元素 第二行為n個數,即每個元素,每個 整數都在32位int範圍內。以空格分隔。輸出描述 所有連續子陣列中和最大的值。示例1 輸入3 1 2 1輸出3 我們用pos代表即將要加的數,sum從0開始一直 pos,並每次進行判斷...