class Solution {
public:
vector<int> buffer; // 辅助数组, 临时保存递归过程有序的部分
vector<int> sortArray(vector<int>& nums) {
int size = nums.size();
buffer.resize(size);
sort(nums, 0, nums.size() - 1);
return nums;
}
void merge(vector<int> &nums, int left, int mid, int right) {
int p1 = left;
int p2 = mid + 1;
int p3 = left;
while (p1 < mid + 1 && p2 < right + 1) {
if (nums[p1] <= nums[p2]) {
buffer[p3++] = nums[p1++];
} else {
buffer[p3++] = nums[p2++];
}
}
while (p1 < mid + 1) {
buffer[p3++] = nums[p1++];
}
while (p2 < right + 1) {
buffer[p3++] = nums[p2++];
}
for (int i = left; i < right + 1; ++i) {
nums[i] = buffer[i];
}
}
void sort(vector<int> &nums, int left, int right) {
if (left >= right) {
return;
}
int mid = (left + right) >> 1;
sort(nums, left, mid);
sort(nums, mid + 1, right);
merge(nums, left, mid, right);
}
};
给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。
你需要返回给定数组中的重要翻转对的数量。
示例 1:
输入: [1,3,2,3,1]
输出: 2
示例 2:
输入: [2,4,3,5,1]
输出: 3
注意:
50000。
class Solution {
public:
vector<int> buffer;
int reversePairs(vector<int>& nums) {
buffer.resize(nums.size());
return help(nums, 0, nums.size() - 1);
}
int help(vector<int>& nums, int left, int right) {
if (left >= right) {
return 0;
}
int mid = (left + right) >> 1;
int l = help(nums, left, mid);
int r = help(nums, mid + 1, right);
return l + r + merge(nums, left, mid, right);
}
int merge(vector<int> &nums, int left, int mid, int right) {
int p1 = left;
int p2 = mid + 1;
int p3 = left;
// 统计数量(修复 *2 溢出)
int i = left, j = mid + 1;
int ans = 0;
while (i < mid + 1) {
while (j < right + 1 && (long long)nums[i] > 2LL * nums[j]) {
++j;
}
ans += j - (mid + 1);
++i;
}
// 合并排序
while (p1 < mid + 1 && p2 < right + 1) {
if (nums[p1] <= nums[p2]) {
buffer[p3++] = nums[p1++];
} else {
buffer[p3++] = nums[p2++];
}
}
while (p1 < mid + 1) {
buffer[p3++] = nums[p1++];
}
while (p2 < right + 1) {
buffer[p3++] = nums[p2++];
}
for (int i = left; i <= right; ++i) {
nums[i] = buffer[i];
}
return ans;
}
};