题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
限制:
0 <= 数组长度 <= 50000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof
思路
c++
class Solution {
public:
int reversePairs(vector<int>& nums) {
int len = nums.size();
int cnts = 0;
vector<int> tmps(len, 0);
mergeSort(nums, tmps, 0, len - 1, cnts);
return cnts;
}
void merge(vector<int>&nums, vector<int>&tmps,
int start, int mid, int end, int &cnts){
int i = start;
int j = mid + 1;
int index = start;
while(i <= mid && j <= end){
if(nums[i] <= nums[j]){
tmps[index++] = nums[i++];
}else{
cnts += (mid - i + 1);
tmps[index++] = nums[j++];
}
}
while(i <= mid)
tmps[index ++] = nums[i++];
while(j <= end)
tmps[index ++] = nums[j++];
while(start <= end){
nums[start] = tmps[start];
start ++;
}
}
void mergeSort(vector<int>&nums, vector<int>&tmps, int start, int end, int &cnts){
if(start >= end) return;
int mid = start + ((end - start)>>1);
mergeSort(nums, tmps, start, mid, cnts);
mergeSort(nums, tmps, mid + 1, end, cnts);
merge(nums, tmps, start, mid, end, cnts);
}
};
python
class Solution:
def reversePairs(self, nums: List[int]) -> int:
self.cnt = 0
def merge(nums, start, mid, end, temp):
i, j = start, mid + 1
while i <= mid and j <= end:
if nums[i] <= nums[j]:
temp.append(nums[i])
i += 1
else:
self.cnt += mid - i + 1
temp.append(nums[j])
j += 1
while i <= mid:
temp.append(nums[i])
i += 1
while j <= end:
temp.append(nums[j])
j += 1
for i in range(len(temp)):
nums[start + i] = temp[i]
temp.clear()
def mergeSort(nums, start, end, temp):
if start >= end: return
mid = (start + end) >> 1
mergeSort(nums, start, mid, temp)
mergeSort(nums, mid + 1, end, temp)
merge(nums, start, mid, end, temp)
mergeSort(nums, 0, len(nums) - 1, [])
return self.cnt