NYOJ-117--求逆序数(归并排序)

求逆序数

 题目链接:求逆序数

题解:题目意思为一组数组中,前面的数比后面的数大,那么这两个就是一对逆序数。然后数列中一共有多少这样的逆序数对。

采用归并排序,先分到最小时,在合并两个数组,当左边的数组大于右边的数组时,即左边这个数的逆序数为右边数组剩下的元素个数。然后以此累加这个逆序数对,直至排序完成,累加所得的结果就是数列中逆序数对。

比如 1 3 4 2 

    NYOJ-117--求逆序数(归并排序)_第1张图片

实现代码

import java.util.Scanner;

public class Main {
	private static long arr[] = new long[1000050];
	private static long temp[] = new long[1000050];
	private static long sum = 0;
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		while (n-- > 0) {
			Main.sum = 0;
			int m = cin.nextInt();
			for (int i = 0; i < m; i++) {
				Main.arr[i] = cin.nextInt();
			}
			sort(0, m - 1);
			System.out.println(Main.sum);
		}
	}

	public static void sort(int left, int right) {
		if (left < right) {
			int mid = (left + right) / 2;
			sort(left, mid);
			sort(mid + 1, right);
			merge(left, mid, right);
		}
	}

	

	public static void merge(int left, int mid, int right) {
		int i = left;
		int j = mid + 1;
		int t = 0;
		while (i <= mid && j <= right) {
			if (Main.arr[i] > Main.arr[j]) {
				Main.sum += ((mid - i) + 1);
				Main.temp[t++] = Main.arr[j++];
			} else {
				Main.temp[t++] = Main.arr[i++];
			}
		}
		while (i <= mid) {
			Main.temp[t++] = Main.arr[i++];
		}
		while (j <= right) {
			Main.temp[t++] = Main.arr[j++];
		}
		for (int k = 0; k < t; k++) {
			Main.arr[left++] = Main.temp[k];
		}
	}
}

 

你可能感兴趣的:(排序算法)