这道题真是难理解!!!!
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
class Solution {
public:
int res=0;
int InversePairs(vector<int> data) {
if(data.size()==0||data.size()==1)
return 1000000007;
vector<int> dup(data.size());
sort(data,dup,0,data.size()-1);
return res%1000000007;
}
void sort(vector<int> &data,vector<int> &dup,
int low,int high)
{
if(low>=high)
return;
int mid=(low+high)/2;
sort(data,dup,low,mid);
sort(data,dup,mid+1,high);
merge_sort(data,dup,low,mid,high);
return;
}
void merge_sort(vector<int> &data,vector<int> &dup,
int low,int mid,int high )
{
int arr1=low,arr2=mid+1;
for(int i=low;i<=high;++i)
dup[i]=data[i];
for(int i=low;i<=high;++i)
{
if(arr1>mid)
data[i]=dup[arr2++];
else if(arr2>high)
data[i]=dup[arr1++];
else if(dup[arr1]<dup[arr2])
data[i]=dup[arr1++];
else{
data[i]=dup[arr2++];
res+=mid-arr1+1;
res%=1000000007;
}
}
return;
}
class Solution {
public:
int InversePairs(vector<int> data) {
if(data.size()<2)
return 0;
return mergesort(data,0,data.size()-1);
}
int mergesort(vector<int> &data,int begin,int end){
if(begin==end)
return 0;
int mid = (begin+end)/2;
int left = mergesort(data,begin,mid);
int right = mergesort(data,mid+1,end);
vector<int> temp(end-begin+1);
int i=begin,j=mid+1;
int cur=0,ret=0;
while(i<=mid && j<=end){
if(data[i]<=data[j])
temp[cur++]=data[i++];
else{
temp[cur++]=data[j++];
ret =(ret + mid-i+1)%1000000007;
}
}
while(i<=mid)
temp[cur++]=data[i++];
while(j<=end)
temp[cur++]=data[j++];
for(int i=begin;i<=end;i++){
data[i]=temp[i-begin];
}
return (ret+left+right)%1000000007;
}
};
class Solution {
public:
int InversePairs(vector<int> data) {
if(data.size()<2)
return 0;
return mergesort(data,0,data.size()-1);
}
int mergesort(vector<int> &data,int begin,int end){
if(begin==end)
return 0;
int mid = (begin+end)/2;
int left = mergesort(data,begin,mid);
int right = mergesort(data,mid+1,end);
vector<int> temp(end-begin+1);
int i=begin,j=mid+1;
int cur=0,ret=0;
while(i<=mid && j<=end){
if(data[i]<=data[j])
temp[cur++]=data[i++];
else{
temp[cur++]=data[j++];
ret =(ret + mid-i+1)%1000000007;
}
}
while(i<=mid)
temp[cur++]=data[i++];
while(j<=end)
temp[cur++]=data[j++];
for(int i=begin;i<=end;i++){
data[i]=temp[i-begin];
}
return (ret+left+right)%1000000007;
}
};
(O(n)复杂度)
public class Solution {
/*
思路如下:
借助一个数组hash,统计array从后往前的情况下,到第i位时候,i后面每个数字出现的次数
1. 从后往前遍历array, hash数组记录数字array[i]已出现的次数
2. 对于数字array[i],统计 array[x](此处 x>i)的的部分,小于array[i]的数字总数 count
count 等于hash数组中 hash[x]的和(此处 x < array[i])
3. count即为 array 数组中, 以第i位开始的子数组的逆序数
*/
public int InversePairs(int [] array) {
if(array == null || array.length == 0) return 0;
int[] hash = new int[10];
int i = array.length-1;
int ans = 0;
for(; i>= 0; i--){
hash[array[i]] ++;
ans += countInversePairs(hash, array[i]);
}
return ans;
}
private int countInversePairs(int[] hash, int target){
int count = 0;
for(int i = 0; i < target; i++){
count += hash[i];
}
return count;
}
}