Que04|788. 逆序对的数量

64 阅读1分钟
题目:788. 逆序对的数量 - AcWing题库
思路:

①暴力超时

②分治思想

在归并排序的基础上,能够顺带计算逆序对的数量。

image.png 分三种情况:如下图

归并排序思路

① 分割区间[L, R] => [L, mid], [mid + 1, R] ②递归排序[L, mid],[mid + 1, R] ③归并,将左右两个有序序列合并成一个有序序列

代码实现:
import java.util.*;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
        }
        // 最大结果为5*10^9,超 int 的取值范围,因此定义为long
        long ans = mergeSort(arr, 0, n - 1);
        System.out.print(ans);
    }
    public static long mergeSort(int[] arr, int l, int r) {
        if (l >= r) return 0;
        // ①分割点
        int mid = (l + r) / 2;
        // ②分别递归
        long ans = mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r);
        // ③操作
        int[] temp = new int[r - l + 1];
        int k = 0, i = l, j = mid + 1;
        while (i <= mid && j <= r) {
            if (arr[i] <= arr[j]) {
                temp[k++] = arr[i++];
            } else {
                temp[k++] = arr[j++];
                ans += mid - i + 1;
            }
        }
        while (i <= mid) temp[k++] = arr[i++];
        while (j <= r) temp[k++] = arr[j++];
        // 物归原主
        for (i = l, j = 0; i <= r; i++, j++) {
            arr[i] = temp[j];
        }
        return ans;
    }
}

// ①暴力超时
import java.util.*;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
        }
        int ans = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (arr[i] > arr[j]) ans++;
            }
        }
        System.out.print(ans);
    }
}