在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

归并排序,时间复杂度o(nlog(n)), 空间复杂度o(n)
class Solution3 {
public:
int reversePairs(vector<int>& nums) {
vector<int> tmp(nums.size(), 0);
return mergeSort(nums, 0, nums.size() - 1, tmp);
}
private:
int mergeSort(vector<int>& nums, int lo, int hi, vector<int> &tmp) {
if (lo >= hi)
return 0;
int mid = (lo + hi) / 2;
int count = mergeSort(nums, lo, mid, tmp) + mergeSort(nums, mid + 1, hi, tmp);
// 对两个有序数组计算逆序对
int p1 = mid;
int p2 = hi;
while (p1 >= lo && p2 > mid) {
if (nums[p1] > nums[p2]) {
count += p2 - mid;
p1--;
continue;
}
p2--;
}
// 对两个有序数组进行排序
p1 = lo;
p2 = mid + 1;
int c = 0;
while (p1 <= mid && p2 <= hi) {
if (nums[p1] <= nums[p2]) {
tmp[c++] = nums[p1++];
continue;
}
tmp[c++] = nums[p2++];
}
while (p1 <= mid)
tmp[c++] = nums[p1++];
while (p2 <= hi)
tmp[c++] = nums[p2++];
// 合并
for (int i = 0; i <= hi - lo; i++)
nums[lo + i] = tmp[i];
return count;
}
};
这里面抽出了一个子问题,就是:两个有序数组的逆序对?
数组1:[2, 6, 8]
数组2:[1, 3, 5, 7]
则组成的逆序对:
[2, 1]
[6, 1]
[6, 3]
[6, 5]
[8, 1]
[8, 3]
[8, 5]
[8, 7]
时间复杂度o(n + m)
int reversePair(vector<int>& nums1, vector<int>& nums2) {
int count = 0;
int p1 = nums1.size() - 1;
int p2 = nums2.size() - 1;
while (p1 >= 0 && p2 >= 0) {
if (nums1[p1] > nums2[p2]) {
count += p2 + 1;
p1--;
continue;
}
p2--;
}
return count;
}
数组逆序对求解

本文介绍了一种利用归并排序算法求解数组中逆序对总数的方法,详细解析了算法实现过程,包括子问题的解决策略,如两个有序数组的逆序对计算,以及如何通过递归和迭代实现整体解决方案。
281

被折叠的 条评论
为什么被折叠?



