[Sword finger offer] _12 Reverse pair in the array

Title description

The two numbers in the array, if the previous number is greater than the latter number, then these two numbers form a reverse order pair. Enter an array to find the total number P of pairs in reverse order in this array. And output the result of modulo P to 1000000007. Ie output P% 1000000007

Problem-solving ideas

Sword finger offer solution
Seeing this problem, our first reaction is to scan the entire array sequentially. Each time an array 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, these two numbers form a reverse pair. Suppose that the array contains n numbers. Since each number must be compared with the number O (n), the time complexity of this algorithm is O (n ^ 2).
Let's take the array {7,5,6,4} as an example to analyze the process of statistical reverse order pairs. Every time we scan a number, we don't compare ta with each subsequent number, otherwise the time complexity is O (n ^ 2), so we can consider comparing two adjacent numbers first.
Insert picture description here
(a) Decompose an array of length 4 into two sub-arrays of length 2;
(b) Decompose an array of length 2 into two sub-arrays of Chengdu;
© Combine sub-arrays of length 1, Sort and count the reverse-order pairs;
(d) Combine and sort the sub-arrays of length 2 and count the reverse-order pairs;
in (a) and (b) above, we first decompose the array into two sub-lengths of 2 Array, and then split the two sub-arrays into two sub-arrays of length 1. Next, while merging adjacent sub-arrays, the number of pairs in reverse order is counted. In the first pair of subarrays of length 1 {7} and {5}, 7 is greater than 5, so (7, 5) form a reverse order pair. Similarly, in the second pair of subarrays of length 1 {6} and {4}, there are also pairs in reverse order (6, 4). Since we have already counted the reverse order pairs inside these two sub-arrays, we need to sort the two pairs of sub-arrays as shown in Figure (c) above, so as not to repeat the statistics in the future statistical process.

Next, we count the reverse pairs between two subarrays of length 2 of the subarray. The process of merging sub-arrays and counting the reverse pairs is shown in the figure below.

We first use two pointers to point to 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 array, the reverse order pairs are formed, and the number of reverse order pairs is equal to the number of remaining numbers in the second sub-array, as shown in (a) and (c) below Show. If the number in the first array is less than or equal to the number in the second array, it does not constitute a reverse order pair, as shown in Figure b. Each time we compare, we copy the larger numbers from the back to the auxiliary array to ensure that the numbers in the auxiliary array (denoted as copy) are sorted in increasing order. After copying the larger number to the auxiliary array, move the corresponding pointer forward one bit, and then perform the next round of comparison.
Insert picture description here
Process: First divide the array into sub-arrays, first count the number of reverse-order pairs within the sub-array, and then count the number of reverse-order pairs between two adjacent sub-arrays. In the process of statistical reverse order pairing, it is also necessary to sort the array. If you are familiar with the sorting algorithm, it is not difficult to find that this process is actually a merge sort.

Code

class Solution {
public:
    int InversePairs(vector<int> data) {
       int length=data.size();
        if(length<=0)
            return 0;
       //vector<int> copy=new vector<int>[length];
       vector<int> copy;
       for(int i=0;i<length;i++)
           copy.push_back(data[i]);
       long long count=InversePairsCore(data,copy,0,length-1);
       //delete[]copy;
       return count%1000000007;
    }
    long long InversePairsCore(vector<int> &data,vector<int> &copy,int start,int end)
    {
       if(start==end)
          {
            copy[start]=data[start];
            return 0;
          }
       int length=(end-start)/2;
       long long left=InversePairsCore(copy,data,start,start+length);
       long long right=InversePairsCore(copy,data,start+length+1,end); 
        
       int i=start+length;
       int j=end;
       int indexcopy=end;
       long long count=0;
       while(i>=start&&j>=start+length+1)
          {
             if(data[i]>data[j])
                {
                  copy[indexcopy--]=data[i--];
                  count=count+j-start-length;          //count=count+j-(start+length+1)+1;
                }
             else
                {
                  copy[indexcopy--]=data[j--];
                }          
          }
       for(;i>=start;i--)
           copy[indexcopy--]=data[i];
       for(;j>=start+length+1;j--)
           copy[indexcopy--]=data[j];       
       return left+right+count;
    }
};
Published 253 original articles · praised 41 · 40,000+ views

Guess you like

Origin blog.csdn.net/liuyuchen282828/article/details/103858021