[Sword refers to Offer learning] [interview question 36: Reverse Order pairs in the array], sword refers to offer
Question: two numbers in the array. If the first number is greater than the next number, the two numbers form a reverse order. Enter an array to find the total number of reverse pairs in this array.Example Analysis
For example, in the array {7, 5, 6, 4, there are five Reverse Order pairs, respectively (7, 6), (7, 5), (7, 4), (6, 4) and (5, 4 ).
Solution:
First: Direct Solution
Scan the entire array sequentially. Each time a number is scanned, the size of the number and the number following it are compared one by one. If the following number is smaller than it, the two numbers form a reverse order. Assume that the array contains n numbers. Since each number must be compared with an O (n) number, the time complexity of this algorithm is O (n ^ 2 ).
Method 2: Analytical Method
We take the Array {7, 5, 6, 4} as an example to analyze the process of counting Reverse Order pairs. Each time a number is scanned, we cannot compare it with each subsequent number. Otherwise, the time complexity is O (n ^ 5 ), therefore, we can consider comparing two adjacent numbers first.
5. as shown in figure 1 (a) and Figure 5.1 (B), we first break down the array into two child arrays with a length of 2, split the two child arrays into two child arrays with a length of 1. Next, merge adjacent sub-arrays and count the number of reverse-order pairs. In the first pair of child arrays {7} and {5} with the length of 1, 7 is greater than 5, so (7, 5) constitute a reverse order. Also, there are reverse orders (6, 4) in the Child arrays {6} and {4} with the length of 1 in the second pair ). As we have counted the reverse pairs in these two pairs of arrays, we need to sort these two pairs of arrays (Figure 5.1 (c ), to avoid repeated statistics in the future statistical process.
NoteThe last step is omitted in the figure, that is, the remaining 4 of the second sub-array is copied to the secondary array.
(A) The number indicated by P1 is greater than the number indicated by P2, indicating that there is a reverse order in the array. p2 points to the second number of the second sub-array, so the second sub-array has two numbers smaller than 7. add 2 pairs in the reverse order, copy 7 to the secondary array, and move P1 and P3.
(B) The number indicated by P1. the number indicated by p2. The number indicated by P2. copy the number indicated by P2. move P2 and P3.
(C) The number indicated by P1 is greater than the number indicated by P2, so there is a reverse order. since P2 points to the number that is the first digit of the second sub-array, only one number in the sub-array is smaller than 5. add 1 to the number of backward pairs, copy 5 to the secondary array, and move P1 and P3 forward.
Next we will calculate the reverse order pairs between two child arrays with a length of 2. In Figure 5.2, we subdivided graph 5.1 (d) into the process of merging sub-arrays and counting backward pairs.
We first use two pointers to respectively the end of the two sub-arrays and compare the numbers pointed to by the two pointers each time. If the number in the first sub-array is greater than the number in the second sub-array, a reverse order is formed, and the number of Reverse Order pairs is equal to the number of the remaining numbers in the second sub-array (5.2 () and figure 5.2 (c ). If the number in the first array is smaller than or equal to the number in the second array, it does not constitute a reverse order (5.2 (B 〉. During each comparison, we copy a large number from the back to a secondary array to ensure that the numbers in the secondary array are sorted progressively. After copying a large number to the secondary array, move the corresponding pointer one byte forward, and then perform the next round of comparison.
After the previous detailed poetry, we can summarize the process of counting Reverse Order pairs: first, we will separate the arrays into subarrays, and first count the number of Reverse Order pairs inside the subarrays, then count the number of reverse pairs between two adjacent sub-arrays. In the process of counting Reverse Order pairs, you also need to sort the array. If you are familiar with the sorting method, it is not difficult to find that the sorting process is actually merge sorting.
Code implementation:
Public class Test36 {public static int inversePairs (int [] data) {if (data = null | data. length <1) {throw new IllegalArgumentException ("Array arg shoshould contain at least a value");} int [] copy = new int [data. length]; System. arraycopy (data, 0, copy, 0, data. length); return inversePairsCore (data, copy, 0, data. length-1);} private static int inversePairsCore (int [] data, int [] copy, int start, int end) {if (start = end) {copy [start] = data [start]; return 0;} int length = (end-start)/2; int left = inversePairsCore (copy, data, start, start + length); int right = inversePairsCore (copy, data, start + length + 1, end ); // The subscript int I = start + length of the last digit in the first half; // The subscript int j = end of the last digit in the second half; // start copy position int indexCopy = end; // Number of reverse orders int count = 0; while (I> = start & j> = start + length + 1) {if (data [I]> data [j]) {copy [indexCopy] = data [I]; indexCopy --; I --; count + = j-(start + length); // Number of reverse orders} else {copy [indexCopy] = data [j]; indexCopy --; j --;}} for (; I> = start; I --) {copy [indexCopy] = data [I]; indexCopy --; I --;} (; j> = start + length + 1; j --) {copy [indexCopy] = data [j]; indexCopy --; j --;} return count + left + right ;} public static void main (String [] args) {int [] data = {1, 2, 3, 4, 7, 6, 5}; System. out. println (inversePairs (data); // 3 int [] data2 = {6, 5, 4, 3, 2, 1}; System. out. println (inversePairs (data2); // 15 int [] data3 = {1, 2, 3, 4, 5, 6}; System. out. println (inversePairs (data3); // 0 int [] data4 = {1}; System. out. println (inversePairs (data4); // 0 int [] data5 = {1, 2}; System. out. println (inversePairs (data5); // 0 int [] data6 = {2, 1}; System. out. println (inversePairs (data6); // 1 int [] data7 = {1, 2, 1, 2, 1}; System. out. println (inversePairs (data7); // 3 }}
Running result
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.