题目:788. 逆序对的数量 - AcWing题库
思路:
①暴力超时
②分治思想
在归并排序的基础上,能够顺带计算逆序对的数量。
分三种情况:如下图
归并排序思路:
① 分割区间[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);
}
}