LCR 170. 交易逆序对的总数 - 力扣(LeetCode)
题目要求:
在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录 record
,返回其中存在的「交易逆序对」总数。
示例 1:
输入:record = [9, 7, 5, 4, 6]
输出:8
解释:交易中的逆序对为 (9, 7), (9, 5), (9, 4), (9, 6), (7, 5), (7, 4), (7, 6), (5, 4)。
限制:
0 <= record.length <= 50000
归并排序 O(NLogN):
把数组分成两份,先找左数组的所有逆序对,升序排序后,再找由数组的所有逆序对,升序排序后,最后找一左一右的逆序对。
假设一左一右:

存在record[cur1]>record[cur2],那么区间[cur1,mid]的元素都可以和record[cur2]构成逆序对。
cpp
class Solution {
vector<int> tmp; // 辅助数组
int ret = 0;
void _reversePairs(vector<int>& record, int sta, int end) {
if (sta >= end)
return;
// 1、找中点划分数组
int mid = sta + (end - sta) / 2;
// 2、分别找左右两边的逆序对数
_reversePairs(record, sta, mid);
_reversePairs(record, mid + 1, end);
// 3、排序两个数组+一左一右找逆序对
int cur1 = sta, cur2 = mid + 1, i = 0;
while (cur1 <= mid && cur2 <= end) {
if(record[cur1]>record[cur2]){
ret+=mid-cur1+1;
tmp[i++]=record[cur2++];
}else{
tmp[i++]=record[cur1++];
}
}
while(cur1 <= mid)
tmp[i++]=record[cur1++];
while(cur2 <= end)
tmp[i++]=record[cur2++];
// 4、将排序好的结果复制到record
for(int i = sta;i <= end;i++){
record[i]=tmp[i-sta];
}
}
public:
int reversePairs(vector<int>& record) {
tmp.resize(record.size());
_reversePairs(record, 0, record.size() - 1);
return ret;
}
};