[Ordenar fusión] -Encontrar el algoritmo ordinal inverso

1. Ordenar fusión

  • Fusionar y ordenar es una aplicación típica del método de divide y vencerás, aplicando pensamiento recursivo, pensando de arriba a abajo: primero suponga que MergeSort()se puede ordenar una matriz fuera de orden, para que pueda comenzar (dividir una matriz en dos partes en promedio), y luego (respectivamente La llamada MergeSort()ordena las dos partes), y finalmente se usa para Merge()fusionar las dos matrices ordenadas en una matriz ordenada.
  • Merge()El método es simple de implementar. Solo necesita administrar dos punteros, que apuntan a las dos matrices a fusionar, y desarrollar una matriz auxiliar para guardar los resultados intermedios. La O(n)complejidad del tiempo se puede completar

2. Número de orden inverso

  • Definición de número ordinal inverso: si i < jy A[i] > A[j]luego la A[i]suma es A[j]el par de números ordinales inversos. El número de pares en orden inverso se llama orden inverso
  • Encontrar el número ordinal se puede obtener administrando dos punteros, escaneando la matriz dos veces y usando métodos de fuerza bruta. Obviamente, la complejidad del tiempo es Θ(n^2).
  • Usando el método de clasificación de fusión, puede hacer una pequeña mejora. En Merge(), combine dos matrices ya ordenadas A y B. Debido a que AB está ordenado, el número de orden inverso de A y B es 0, por lo que el número de orden inverso de AB es igual al número de orden inverso entre A y B.
  • Por ejemplo: A=1,4,6,7,9., B=2,3,5,10,13,21Merge encontró que el número actual del elemento 4 i mayor que 2, entonces el número requerido de marcha atrás 4 + 1, porque la parte posterior 4 están clasificados en el 6,7,9, 6,7,9, entonces el orden inverso del número de También debe ser +1, por lo que se debe agregar el número de orden inverso general last-i+1.
    Inserte la descripción de la imagen aquí
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
    public int InversePairs(int[] array) {
        int len = array.length;
        int[] c = new int[len];
        count = 0;
        MergeSort(array, 0, len - 1, c);
        return count;
    }

    public static int MOD = 1000000007;
    public static int count = 0;//新增

    public static void Merge(int[] array, int left, int mid, int right, int[] c) {
        int i = left;
        int j = mid + 1;
        int k = left;
        while (i <= mid && j <= right) {
            if (array[i] <= array[j])
                c[k++] = array[i++];
            else {
                c[k++] = array[j++];
                //count += mid - i + 1;//新增
                count = (count + mid - i + 1) % MOD;
            }
        }
        while (i <= mid)
            c[k++] = array[i++];
        while (j <= right)
            c[k++] = array[j++];
        //C数组已经有序,将数组复制回原数组
        for (int in = left; in <= right; in++) {
            array[in] = c[in];
        }
    }

    public static void MergeSort(int[] array, int left, int right, int[] c) {
        if (left < right) {
            int mid = (left + right) / 2;
            MergeSort(array, left, mid, c);   //将第一个数组排好
            MergeSort(array, mid + 1, right, c);    //将第二个数组排好
            Merge(array, left, mid, right, c);     //合并两个有序数组
        }
    }
}
Publicado 395 artículos originales · ganó 130 · 200,000 vistas +

Supongo que te gusta

Origin blog.csdn.net/qq_40507857/article/details/103802860
Recomendado
Clasificación