剑指offer35--数组中的逆序对
作者:互联网
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
思路
首先想到的就是暴力求解,一个个来比较。
不出意外,超时了。
class Solution {
public:
int InversePairs(vector<int> data) {
if (data.size() == 0)
return 0;
vector<int> v=data;
sort(v.begin(), v.end());
int sum;
vector<int>::iterator itr = data.begin();
for (int i = 0; i < v.size(); i++)
{
int position = 0;
while (itr != data.end())
{
if (*itr == v[i])
{
sum += position;
data.erase(itr);
position = 0;
itr= data.begin();
break;
}
position++;
itr++;
}
}
return sum % 1000000007;
}
};
**正确的思路:**归并排序
比普通的归并排序的不同之处是要在归并的途中进行计数。
class Solution {
public:
void sort(vector<int> &data,vector<int> &temp,int l,int mid,int r,int &count)
{
int i=l,j=mid+1,k=0;
while(i<=mid&&j<=r)
{
if (data[i]>data[j])
{
temp[k]=data[j];//如果左边的比右边的大,就先把右边的暂存到辅助数组里面
k++;j++;
count+=mid-i+1;//左边第i个比右边的第j个大,那么左边第i个之后的都比右边第j个大
//(因为在上次递归的时候每个分区已经是有序的了)
count%=1000000007;
}
else
{
temp[k]=data[i];//如果左边分区的没有比右边大就把左边该位置的暂存进辅助数组
k++;i++;
}
}
//下面两个while是将data刚刚没有处理的数据放入辅助数组
while (i<=mid)
{
temp[k]=data[i];
k++;i++;
}
while (j<=r)
{
temp[k]=data[j];
k++;j++;
}
//最后把此次归并的结果又放回原来的数组,递归返回到上一层
for (k=0,i=l;i<=r;i++,k++)
{
data[i]=temp[k];
}
}
void merge(vector<int> &data,vector<int> &temp,int l,int r,int &count)
{
if (l>=r) return;
int mid=l+(r-l)/2;
merge(data,temp,l,mid,count);//左归并
merge(data,temp,mid+1,r,count);//右归并
sort(data,temp,l,mid,r,count);//排序
}
int InversePairs(vector<int> data) {
int count=0;//逆序计数
vector<int> temp(data.size());//用一个数组来暂存当此排序的结果
merge(data,temp,0,data.size()-1,count);
return count;
}
};
标签:count,temp,--,++,offer35,int,vector,data,逆序 来源: https://blog.csdn.net/qq_41565359/article/details/113813395