[Jianzhi offer] 35. Reversed pairs in the array

topic

Two numbers in the array, if the previous number is greater than the following number, the two numbers form a reverse pair. Enter an array and find the total number P of reversed pairs in this array. And output the result of P modulo 1000000007. That is, output P%1000000007

Input description: The title guarantees that there are no identical numbers in the input array

data range:

  1. For %50 data, size<=10^4
  2. For the data of %75, size<=10^5
  3. For the data of %100, size<=2*10^5

Example 1
input
1,2,3,4,5,6,7,0
output
7


analyze

The idea that this question belongs to the best list is to traverse the array and find the number of elements smaller than itself after each element, but the time complexity of this idea is O ( n 2 ) O(n^2)O ( n2 ), this approach is not efficient enough. A more efficient idea is to use the idea of ​​​​merge sorting to solve it. The main ideas are as follows:

  1. Divide the data into two arrays (recursively divided into each array with only one data item);
  2. Merge arrays. When merging, if the previous array value array[i] is greater than the latter array value array[j]; then the previous arrays array[i]~array[mid] are all greater than array[j], count += mid +1 - i

github link: JZ35 - Reversed pairs in an array


C++ code

#include <iostream>
#include <vector>
using namespace std; 

class Solution {
    
    
	public:
	    int InversePairs(vector<int> data) {
    
    
	    	int len = data.size();
			if(len <= 0){
    
    
				return 0;
			}
			vector<int> copy;
			for(int i = 0 ; i < len ; i++){
    
    
				copy.push_back(data[i]);
			}
			long long cnt = this->InversePairsCore(data,copy,0,len-1);
			return cnt % 1000000007;
	    }
	    
	    long long InversePairsCore(vector<int> &data,vector<int> &copy,int start,int end){
    
    
	    	if(start == end){
    
    
	    		copy[start] = data[start];
	    		return 0;
			}
			int len = (end - start) / 2;
			long long left = this->InversePairsCore(copy,data,start,start+len);
			long long right = this->InversePairsCore(copy,data,start+len+1,end);
			
			int i = start + len;
			int j = end;
			int indexcopy = end;
			long long cnt = 0;
			while(i >= start && j >= start+len+1){
    
    
				if(data[i] > data[j]){
    
    
					copy[indexcopy--] = data[i--];
					cnt = cnt + j - start -len;
				}else{
    
    
					copy[indexcopy--] = data[j--];
				}
			}
			for(; i >= start ; i--){
    
    
				copy[indexcopy--] = data[i];
			}
			for(; j >= start+len+1 ; j--){
    
    
				copy[indexcopy--] = data[j];
			}
			return left+right+cnt;
		}
};

int main()
{
    
    
	int n;
	while(cin>>n){
    
    
		vector<int> ans(n);
		for(int i = 0 ; i < n ; i++){
    
    
			cin>>ans[i];
		}
		Solution s;
		cout<<s.InversePairs(ans);
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_30091945/article/details/107454058