在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
限制:
0 <= 数组长度 <= 50000
题解:最容易想到的就是暴力,但是这样会超时,用归并排序就行了。举个例子 比如现在归并排序到了 1 5 6 2 4 8,将数组分为1 5 6和2 4 8,然后进行一次归排,不熟悉归排的可以去看一下归排。1比2小,这时候不产生逆序对,然后后面5比2大,这样就产生逆序对了,不止产生一对,从5到左边数组末尾都比2要大,所以这没个数都会和2产生一对逆序对,我们假设此时左边数组在的下表为lindex,左右数组是在m处分开的,即会产生m-lindex+1个逆序对。
class Solution {
int ans;
int t[];
void mergeSort(int nums[],int l,int r)
{
if(l>=r)
return;
int m=l+(r-l)/2;
mergeSort(nums, l, m);
mergeSort(nums, m+1, r);
merge(nums, l, r, m);
}
void merge(int nums[],int l,int r,int m)
{
int lindex=l,rindex=m+1;
int start=l;
while(lindex<=m&&rindex<=r)
{
if(nums[lindex]<=nums[rindex])
{
t[start++]=nums[lindex++];
}
else
{
ans+=m-lindex+1;
t[start++]=nums[rindex++];
}
}
//1 5 6 2 4 8
//1 2
while(lindex<=m)
t[start++]=nums[lindex++];
while(rindex<=r)
t[start++]=nums[rindex++];
for(int i=l;i<=r;i++)
{
nums[i]=t[i];
}
}
public int reversePairs(int[] nums) {
ans=0;
t=new int[nums.length];
mergeSort(nums, 0, nums.length-1);
return ans;
}
}
然后再最好还有个问题,是我做题的时候遇到的,就是归并排序需要的这个数组t,我一开始是在merge函数里直接申请一个临时数组,然后每次初始化,结果就超时了,换成全局变量就不超时了,是因为Java的垃圾回收机制吗?有懂的小伙伴给我解惑一下呗