在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。给你一个数组,求出这个数组中逆序对的总数。
看到网上有段代码很简洁,记录一下:
概括:如果a[i] > a[j] 且 i < j, a[i] 和 a[j] 构成一个逆序对。
样例
序列 [2, 4, 1, 3, 5]
中,有 3 个逆序对 (2, 1)
, (4, 1)
, (4, 3)
,则返回 3
。
思路:利用归并排序,可以求出逆序对
class Solution {
public:
/**
* @param A an array
* @return total of reverse pairs
*/
long long res=0; //逆序对数
long long reversePairs(vector<int>& A) {
mergesort( A, 0, A.size()-1);
return res;
}
//归并排序
void mergesort(vector<int>& A, int start, int end)
{
int mid = (start + end)/2;
if(start<end)
{
mergesort(A, start, mid);// 左边排序
mergesort(A, mid+1, end);// 右边排序
merge(A, start, mid, end);// 左右合并
}
}
void merge(vector<int>& A, int start, int mid, int end)
{
vector<int> temp(end-start+1);
int i = start;// 左指针
int j = mid+1;// 右指针
int t = 0;
while(i<=mid && j<=end) // 把较小的数先移到新数组中
{
//从小到大排序
if(A[i]<=A[j])
temp[t++] = A[i++];
else
{
res += mid-i+1;
temp[t++] = A[j++];
}
}
while(i<=mid)// 把左边剩余的数移入数组
temp[t++] = A[i++];
while(j<=end) // 把右边边剩余的数移入数组
temp[t++] = A[j++];
for (int k = 0; k < temp.size(); k++) {// 把新数组中的数覆盖nums数组
A[k + start] = temp[k];
}
}
};
看到网上有段代码很简洁,记录一下:
long long reversePairs(vector<int>& A) {
long long res = 0;
vector<int> v;
for (int i = A.size() - 1; i >= 0; --i) {
int left = 0, right = v.size();
while (left < right) {
int mid = left + (right - left) / 2;
if (A[i] > v[mid]){
left = mid + 1;
}else{
right = mid;
}
}
v.insert(v.begin() + right, A[i]);// 在 位置插入A[i]
res += right;
}
return res;
}