Give us a sequence and let us calculate its number in reverse order:
For example, 3 2 1 4
Number of reverse orders: 2 + 1 + 0 + 0 = 3
In this way, we define the reverse number of a sequence: sequence A1 A2 A3 A2...
The number C in the descending order of this sequence is equal to the sum of the numbers in the descending order of A1, a2..., that is, c = sum (CI)
CI is the total number of numbers that meet AI> AJ (j> I), that is, CI = sum (AI> AJ) (j> I ).
We generally write the algorithm will do n (N-1)/2 comparisons, time complexity: O (N ^ 2 ).
The following uses the divide and conquer idea to improve:
Let's assume that the sequence A1 A2 A3 A2... an is divided into two parts: b0 = (A1 A2 an/2) b1 = (a (n/2 + 1 )... an)
C = C (B0) + C (B1) + M (b0b1)
If we calculate M (b0b1), F (n) = 2 * F (n/2) + C * n ^ 2, the calculated result is F (n) = N * F (1) + 2C * n ^ 2-2C * n, so the efficiency is still O (N ^ 2). How can we improve it?
It would be nice to order B0 and B1! Well, that's right. in the process of merging and sorting, we first arrange B0 and B1 in an ordered series, and then find the reverse Number of B0 'b1 '. Then we find M (B0 'b1 ′) efficiency is O (n ).
That is, C = C (b0') + C (b1 ') + M (b0' B1 ′).
The following code is used to evaluate C (B0 'b1 '). You can also find it in the complete reverse order number search algorithm below:
Int I = x, j = m; // sequence B0 [x, y], B1 [M, N] <br/> for (I = x; I <= y; + + I) <br/> {<br/> while (j <= N & arr [I]> arr [J]) <br/> + J; <br/> norder + = J-m; <br/>}
F (n) = 2 * F (n/2) + C * n. the result I calculated is F (n) = N * F (1) + C * n * log (N)
The time complexity O (N * logn) and space complexity O (n) are the same as those of the merge algorithm, which is only a constant factor greater than the merge algorithm.
Welcome.
# Include <iostream> <br/> # include <algorithm> <br/> using namespace STD; <br/> void swap (int * arr, int I, Int J) <br/>{< br/> int TMP = arr [I]; <br/> arr [I] = arr [J]; <br/> arr [J] = TMP; <br/>}< br/> int Merge (int * temp, int * arr, int X, int y, int m, int N) <br/> {<br/> int norder = 0; <br/> int I = x, j = m; <br/> for (I = X; I <= y; ++ I) <br/>{< br/> while (j <= N & arr [I]> arr [J]) <br/> ++ J; <br/> norder + = J-m; <br/>}< br/> int K = 0; <br/> I = x, j = m; <br/> while (I <= Y & J <= N) <br/> {<br/> If (ARR [I] <= arr [J]) <br/> temp [k ++] = arr [I ++]; <br/> else <br/> temp [k ++] = arr [J ++]; <br/>}< br/> while (I <= y) <br/> temp [k ++] = arr [I ++]; <br/> while (j <= N) <br/> temp [k ++] = arr [J ++]; <br/> return norder; <br/>}< br/> int inversion_number (int * arr, int I, Int J) <br/>{< br/> if (I <j) <br/>{< br/> int mid = I + (J-I)> 1); <br/> int V1 = inversion_number (ARR, I, mid); <br/> int v2 = inversion_number (ARR, Mid + 1, J); <br/> int temp [10]; <br/> int nvalue = Merge (temp, arr, I, mid, Mid + 1, J); <br/> memcpy (ARR + I, temp, sizeof (INT) * (J-I + 1); <br/> return V1 + V2 + nvalue; <br/>}< br/> else <br/> return 0; <br/>}< br/> int main () <br/> {<br/> int arr [] = {5, 3, 3, 3, 3, 3, 3 }; <br/> cout <inversion_number (ARR, 0, 9) <Endl; <br/> return 0; <br/>}