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/

上一篇:《寒假每日一题》2022/1/2 AcWing 2058.笨拙的手指


下一篇:Acwing基础课每日一题 第十一天 795-简单-前缀和