[51]数组中的逆序对
文章目录
题目
在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
输入一个数组,求出这个数组中的逆序对的总数。
在数组[7,5,6,4]中,一共有5个逆序对
分别是(7、5)、(7、6)、(7、4)、(6、4)、(5、4)
思路
直接暴力
class Solution {
public:
int inversePairs(vector<int>& nums) {
int res=0;
for(int i=0;i<nums.size();i++)
for(int j=i+1;j<nums.size();j++)
if(nums[i]>nums[j])
res++;
return res;
}
};
递归【归并排序】
时间复制度:nlogn
我们进行一次归并排序,并在归并过程中计算逆序对,换句话说——逆序对是归并排序的副产物
在合并的过程中,统计逆序数
[1,2,3,4] [2,5]
i j
------------------------
nums[i] <= nums[j], i++
[1,2,3,4] [2,5]
i j
nums[i] > nums[j]
res = mid -i +1;
// 统计逆序对 (3,2) (4,2)
------------------------
class Solution {
public:
int merge(vector<int>& nums, int l ,int r)
{ // 归并排序过程
if(l >= r) return 0;
int mid = l + r >> 1;
int res = merge(nums, l, mid) + merge(nums, mid+1, r); // 左右两边计算
int i = l, j = mid+1;
vector<int> temp;
while(i <= mid && j <= r)
{
if(nums[i] < nums[j]) temp.push_back(nums[i++]);
else
{
temp.push_back(nums[j++]);
res += mid - i + 1; // 统计逆序对
}
}
while(i<=mid) temp.push_back(nums[i++]);
while(j<=r) temp.push_back(nums[j++]);
i = l;
for(auto x:temp) nums[i++] =x;
return res;
}
int inversePairs(vector<int>& nums)
{
return merge(nums, 0, nums.size()-1);
}
};