题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例1
输入
1,2,3,4,5,6,7,0
输出
7
分析:
归并排序的主要思想就是“先分后治”。
直接看下面的例子:
1.
首先第一步是“分”,每次将数组分成平均的两部分,直到每一小部分只有一个元素。
第二步是“治”,按照归并排序的比较规则进行元素间的比较,得到有序序列。
图一中,有数组【3, 6, 4, 7, 9, 0, 2】,用土色笔写了元素间的比较。
2.
如图二所示,将前面元素大于后面元素的都挑出来(绿色笔圈起来的),它们与逆序对有直接关联。
3.
如图三所示,假设左右两部分为【】和【】,
对于每一个“”,都有,它们都是逆序对,所以计数个数为,(绿色方框中的元素都是大于绿色圈右边元素的)
以最后一步为例:左边【3, 4, 6, 7】,右边【0, 2, 9】
- 3先和0比较,3 > 0,而且左边是有序序列,因为3>0所以3之后的元素(4, 6, 7)> 0所以计数为4个。将较小值0放到结果序列的第一个位置。
- 3再和2比较,3 > 2,同理(4, 6, 7)> 2,计数为4,将较小值2放到结果序列的后面。
- 3和9比较,3 < 9,不计数,将较小值3放到结果序列的后面。
- ...
- 7和9比较,7 < 9,不计数,将较小值7放到结果序列的后面。
- 最后只剩下9,将9放在结果序列的后面,得到有序的结果序列【0, 2, 3, 4, 6, 7, 9】,同时完成逆序对的计数。
4.
图四所示,将所有绿色框内的元素个数加起来就是答案。
C++版:
class Solution {
private:
vector<int> a;
int count;
public:
void mergeArray(int first,int mid,int last,int temp[])
{
int i=first,j=mid+1;//两部分数组开始下标
int m=mid,n=last; //两部分数组结束坐标
int k=0;
while(i<=m&&j<=n)
{
if(a[i]<=a[j])
temp[k++] = a[i++];
else
{
count += (m - i + 1);
count %= 1000000007;
temp[k++] = a[j++];
}
}
while(i <= m)
temp[k++] = a[i++];
while(j<=n)
temp[k++] = a[j++];
for(int i=0; i<k; i++)
a[first+i]=temp[i];
}
void mergeSort(int first,int last,int temp[])
{
if(first<last)
{
int mid = (first+last)/2;
mergeSort(first,mid,temp);
mergeSort(mid+1,last,temp);
mergeArray(first,mid,last,temp);
}
}
int InversePairs(vector<int> data) {
a = data;
int n = data.size();
int temp[n+1];
mergeSort(0,n-1,temp);
return count%1000000007;
}
};
Python版:
用Python写的同样的算法,但是Python会超时。
下面这段代码是超时的,可以忽略!
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.count = 0
def InversePairs(self, data):
# write code here
def mergeArray(first, mid, last):
i = first
en1 = mid
j = mid + 1
en2 = last
temp = []
while i<=en1 and j<=en2:
if data[i] <= data[j]:
temp.append(data[i])
i += 1
else:
self.count += (en1 - i + 1)
temp.append(data[j])
j += 1
while i <= en1:
temp.append(data[i])
i += 1
while j <= en2:
temp.append(data[j])
j += 1
data[first:first+len(temp)]=temp
def mergeSort(first, last):
if first < last:
mid = (first + last) // 2
mergeSort(first, mid)
mergeSort(mid+1, last)
mergeArray(first, mid, last)
mergeSort(0, len(data)-1)
return self.count % 1000000007