“`java
//没想出来
class Solution {
public int reversePairs(int[] record) {
//使用归并排序的思想
return mergeSort(record, 0, record.length – 1);
}
public int mergeSort(int[] record, int left, int right) {
if (left >= right) {
return 0;
}
int mid = left + (right - left)/2;
int x1 = mergeSort(record, left, mid);
int x2 = mergeSort(record, mid + 1, right);
int x3 = merge(record, left, mid, mid + 1, right);
return x1 + x2 + x3;
}
public int merge(int[] record, int l1, int r1, int l2, int r2) {
int [] tmp = new int[r2 - l1 + 1];
int count = 0;
int i = l1;
int j = l2;
int k = 0;
while (i <= r1 && j <= r2) {
if (record[i] > record[j]) {
count += l2 - i;
tmp[k++] = record[j++];
} else {
tmp[k++] = record[i++];
}
}
while (i <= r1) tmp[k++] = record[i++];
while (j <= r2) tmp[k++] = record[j++];
for (i = l1; i <= r2; i++) {
record[i] = tmp[i - l1];
}
return count;
}
class Solution {
std::vector<int> tmp;
int mergeSort(vector<int>& nums, int left, int right) {
if (left >= right) return 0;
// optimization
if (right - left == 1) {
if (nums[left] > nums[right]) {
std::swap(nums[left], nums[right]);
return 1;
} else return 0;
}
// sort left part and right part respectively
int mid = (left + right) / 2;
int result = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right);
// merge left and right part together
int l = left, r = mid + 1, k = l;
while(l <= mid || r <= right) {
if (r > right || (l <= mid && nums[l] <= nums[r])) {
result += r - (mid + 1);
tmp[k++] = nums[l++];
} else tmp[k++] = nums[r++];
}
for (k = left; k <= right; k++) nums[k] = tmp[k];
return result;
}
public:
int reversePairs(vector<int>& nums) {
tmp.resize(nums.size());
return mergeSort(nums, 0, nums.size() - 1);
}
};
共以下 13 个回答
“`java
//没想出来
class Solution {
public int reversePairs(int[] record) {
//使用归并排序的思想
return mergeSort(record, 0, record.length – 1);
}
}
class Solution {
public int reversePairs(int[] nums) {
return mergesort(nums,0,nums.length-1);
}
int mergesort(int[] nums,int left,int right){
if(left>=right){
return 0;
}
int mid = (left+right)/2;
int x1 = mergesort(nums,left,mid);
int x2 = mergesort(nums,mid+1,right);
int x3 = merge(nums,left,mid,mid+1,right);
return x1+x2+x3;
}
int merge(int[] nums,int l1,int r1,int l2,int r2){
int[] tmp = new int[r2-l1+1];
int i = l1,j=l2,count=0,k=0;
while(i<=r1&&j<=r2){
if(nums[i]>nums[j]){
count=count+(l2-i);
tmp[k++]=nums[j++];
}else{
tmp[k++]=nums[i++];
}
}
while(i<=r1){
tmp[k++]=nums[i++];
}
while(j<=r2){
tmp[k++]=nums[j++];
}
k=0;
for(i=l1;i<=r2;i++){
nums[i]=tmp[k++];
}
return count;
}
}
归并排序
【思路】采用mergeSort的方法,每一次递归先统计左右两个子数组的逆序对数量,归并时再统计跨子树组的逆序对数量
【复杂度】时间复杂度O(nlogn),空间复杂度O(n)
“`C++& nums, vector & temp, int left, int right) {
int mergeSort(vector
// 递归终止条件:当子数组只包含一个元素时,无逆序对
if (left >= right) return 0;
}
int reversePairs(vector& nums) { temp(n);
int n = nums.size();
vector
return mergeSort(nums, temp, 0, n – 1);
}
“`
时间复杂度:O(nlogn)
空间复杂度:O(n)
归并排序,每合并时若右边大于左边,就会有l2-i个逆序对
国际站
我也只会暴力,看官解
只会暴力。还是得看题解
时间复杂度O(nlogn)
MY493 翻转对