暴力法
O(n^2), 简单且超时…
class Solution {
public:
int cnt = 0;
int reversePairs(vector<int>& nums) {
int n = nums.size();
for(int i = 0; i < n-1; ++i){
for(int j = i+1; j < n; ++j){
if(long(nums[i]) > 2*long(nums[j])) ++cnt;
}
}
return cnt;
}
};
归并
和下面两个很像:
LeetCode第 327 题:区间和的个数(C++)_qq_32523711的博客-CSDN博客
剑指 Offer 51. 数组中的逆序对_qq_32523711的博客-CSDN博客
class Solution {
public:
int cnt = 0;
vector<int> tmp;//只申请一次tmp数组
void merge(vector<int> &nums, int beg, int mid, int end){
int i = beg, j = mid+1;
int k = 0;
while(i <= mid && j <= end){
if(nums[i] <= nums[j]) tmp[k++] = nums[i++];
else tmp[k++] = nums[j++];
}
while(i <= mid) tmp[k++] = nums[i++];
while(j <= end) tmp[k++] = nums[j++];
copy(tmp.begin(), tmp.begin() + k, nums.begin() + beg);
}
void merge_sort(vector<int> &nums, int beg, int end){
if(beg >= end) return;
int mid = beg + (end - beg)/2;
merge_sort(nums, beg, mid);
merge_sort(nums, mid+1, end);
//计算符合要求的翻转对数目
int i = beg, j = mid+1;
while(j <= end){ //对于右半部分的每个元素
while(i <= mid && long(nums[i]) <= 2*long(nums[j])) ++i;
cnt += mid - i + 1;
++j;
}
if(nums[mid] <= nums[mid+1]) return; //加一个判断,此时数组已经是有序的,不用进行后续操作了
merge(nums, beg, mid, end);
}
int reversePairs(vector<int>& nums) {
int n = nums.size();
tmp = vector<int>(n);
merge_sort(nums, 0, n-1);
return cnt;
}
};