在归并排序过程中,我们有一步判断:if(nums[i] > nums[j]) ,如果该条件为真,那么 nums[j] 和 区间 [i,mid] 中每一个数都会形成逆序对,一共mid-i+1个,而且只在这个地方会出现形成逆序对的情况。因此,我们将原数组进行归并排序,并且在if(nums[i] > nums[j])为真的时候,统计一下逆序对的个数即可。
import java.util.Arrays;
public class NiXuDui {
static long ans = 0;
public static void main(String[] args) {
int[] nums = {4, 1, 3, 2, 0};
mergeSort(nums, 0, nums.length - 1);
System.out.println(Arrays.toString(nums));
System.out.println(ans);
}
public static void mergeSort(int[] nums, int left, int right){
if(right > left){
int mid = (left + right) / 2;
mergeSort(nums, left, mid);
mergeSort(nums, mid + 1, right);
merge(nums, left, mid, right);
}
}
public static void merge(int[] nums, int left, int mid, int right){
int[] temp = new int[right - left + 1];
int t = 0;
int i = left;//i表示左边有序序列的初始下标
int j = mid + 1;//j表示右边有序序列的初始下标
while(i <= mid && j <= right){
if(nums[i] > nums[j]){
temp[t++] = nums[j++];
ans += mid - i + 1;//本步就是在求逆序对数量
}else{
temp[t++] = nums[i++];
}
}
while(i <= mid){
temp[t++] = nums[i++];
}
while(j <= right){
temp[t++] = nums[j++];
}
t = 0;
while(left <= right){
nums[left++] = temp[t++];
}
}
}