剑指 Offer 51. 数组中的逆序对
求逆序对的例题
思路
求逆序对一般有两种解法:1 是归并排序,2是树状数组,使用树状数组的时候一般需要对数据进行你离散化,而归并排序不需要。
归并排序是在归并的时候进行答案统计,因为归并的时候两个序列都是有序的,所以如果左序列的某一个元素大于右序列的某个元素,那么左序列这个元素后面的元素也会大于有序列的这个元素
注意点:要提前声明一个大小与原数组相同的数组,不要在函数里面声明!
代码
class Solution {
public:
int mergeSort(vector<int> &nums, int l, int r, vector<int> &tmp) {
if (l >= r) {
return 0;
}
int mid = (l + r) / 2;
int ans = mergeSort(nums, l, mid, tmp) + mergeSort(nums, mid+1, r, tmp);
for (int k = l; k <= r; ++k) {
tmp[k] = nums[k];
}
int i = l, j = mid + 1, k = l;
while (i <= mid && j <= r) {
if (tmp[i] > tmp[j]) {
ans += mid - i + 1;
nums[k++] = tmp[j++];
} else {
nums[k++] = tmp[i++];
}
}
while (i <= mid) nums[k++] = tmp[i++];
while (j <= r) nums[k++] = tmp[j++];
return ans;
}
int reversePairs(vector<int>& nums) {
vector<int> tmp(nums.size());
return mergeSort(nums, 0, nums.size() - 1, tmp);
}
};