AcWing刷题——逆序对的数量(经典逆序对)
题目描述
给定一个长度为 n的整数数列,请你计算数列中的逆序对的数量。
逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i < j 且 a[i] > a[j],则其为一个逆序对;否则不是。
输入格式
第一行包含整数n ,表示数列的长度。
第二行包含n个整数,表示整个数列。
输出格式
输出一个整数,表示逆序对的个数。
数据范围
1 <= n <= 100000,
数列中的元素的取值范围 [1, 10^9]。
输入样例:
6 2 3 4 5 6 1
输出样例:
5
Java代码
1 import java.util.*; 2 3 public class Main { 4 5 private static long res = 0; 6 public static void main(String[] args) { 7 Scanner input = new Scanner(System.in); 8 int n = input.nextInt(); 9 int[] arr = new int[n]; 10 for (int i = 0; i < n; i++ ) { 11 arr[i] = input.nextInt(); 12 } 13 // 归并排序 14 mergeSort(0, n - 1, arr); 15 System.out.println(res); 16 } 17 18 public static void mergeSort(int l, int r, int[] arr) { 19 if (l >= r) { 20 return; 21 } 22 int mid = (l + r) / 2; 23 mergeSort(l, mid, arr); 24 mergeSort(mid + 1, r, arr); 25 int i = l, j = mid + 1, k = 0; 26 int[] tmp = new int[r - l + 1]; 27 while (i <= mid && j <= r) { 28 if (arr[i] <= arr[j]) { 29 tmp[k++] = arr[i++]; 30 } else { 31 tmp[k++] = arr[j++]; 32 res += (mid - i + 1); 33 } 34 } 35 while (i <= mid) { 36 tmp[k++] = arr[i++]; 37 } 38 while (j <= r) { 39 tmp[k++] = arr[j++]; 40 } 41 // 最后将临时数组存储到arr中 42 for (int m = l, n = 0; m <= r; m++, n++) { 43 arr[m] = tmp[n]; 44 } 45 } 46 }
原题链接:https://www.acwing.com/problem/content/790/