LeetCode: 1. Algoritmo de clasificación rápida

1. Idea básica

  El algoritmo de clasificación rápida (clasificación rápida) es una mejora del algoritmo de burbujas y es un algoritmo de clasificación inestable. La idea principal es dividir los datos que se clasificarán en dos partes independientes mediante una clasificación, todos los datos de una parte son más pequeños que todos los datos de la otra parte, y luego las dos partes de los datos se ordenan rápidamente de acuerdo con este método. Todo el proceso de clasificación se puede realizar de forma recursiva y, finalmente, todos los datos se convierten en una secuencia ordenada.

Bubble Sort es un algoritmo de clasificación simple. Recorre repetidamente la secuencia de números que se van a clasificar, compara dos elementos a la vez y los intercambia si están en el orden incorrecto. El trabajo de atravesar la secuencia se repite hasta que no se necesitan más intercambios.
El funcionamiento del algoritmo de clasificación de burbujas es el siguiente:
1. Compare elementos adyacentes. Si el primero es mayor que el segundo (orden ascendente), intercambie los dos.
2. Haga el mismo trabajo para cada par de elementos adyacentes, desde el primer par al principio hasta el último par al final. Una vez realizado este paso, el último elemento será el número más grande.
3. Repita los pasos anteriores para todos los elementos excepto el último.
4. Continúe repitiendo los pasos anteriores para cada vez menos elementos hasta que no haya un par de números para comparar.

2. Principio de algoritmo

  El algoritmo de clasificación rápida funciona de la siguiente manera:

  1. Elija un elemento de la secuencia, llamado pivote,
  2. Reordene la secuencia numérica, todos los elementos más pequeños que el valor de referencia se colocan delante de la referencia y todos los elementos mayores que el valor de referencia se colocan detrás de la referencia (el mismo número puede ir a cualquier lado). Una vez finalizada la operación de partición, el elemento de referencia está en su posición después de la clasificación final.
  3. Ordene de forma recursiva las subsecuencias de elementos menores que el valor de referencia y las subsecuencias de elementos mayores que el valor de referencia hasta que solo quede un elemento en todas las subsecuencias

3. Partición: partición

  Simplemente domina uno de los siguientes dos métodos

1. Método de excavación

Inserte la descripción de la imagen aquí

Al principio, hay punteros debajo de 4 y 1, respectivamente, correspondientes a los punteros ly r. El primer hoyo es 4. Dado que el 1 al que apunta el puntero r es menor que 4, 1 se mueve al hoyo apuntado a por el puntero l, que ahora es 1 La fuente es un pozo, el puntero l se mueve un bit hacia la derecha, apuntando a 7, porque el 7 apuntado por el puntero l es mayor que 4, por lo que 7 se mueve al pozo señalado a por el puntero l. En este momento, el 7 original es un pozo. Repita la operación hasta que el puntero l y r Los punteros coincidan, y la posición sea 4. La
operación de partición se completa arriba,
y luego recursivamente clasifique el sub- secuencias del elemento menores que el valor de referencia y las subsecuencias del elemento mayores que el valor de referencia hasta que solo quede una subsecuencia Elemento hasta el momento

2. Método de intercambio de punteros

  La idea central es encontrar los punteros que no cumplan con las condiciones en ambos lados y luego intercambiar los punteros.
Inserte la descripción de la imagen aquí

El punto de referencia es 4, el puntero l apunta a 7, el puntero r apunta a 1, porque 1 <4 <7, la condición no se cumple, por lo que los dos punteros se intercambian, el puntero r se mueve un bit, 1 <4 <8, cuando se cumple la condición, el puntero r se mueve un bit, 1 <4 <2 El lado derecho no cumple la condición, el lado izquierdo debe moverse, el puntero l se mueve un bit, 6 <4 < 2, ambos lados no cumplen las condiciones, los dos punteros se intercambian, el puntero r se mueve un bit, 2 <4 <3, el lado derecho no cumple la condición, el puntero l se mueve un bit, 5 <4 <3 , los dos punteros se intercambian y el puntero r se mueve un bit hacia la izquierda. En este momento, los punteros dobles se fusionan para apuntar al 3, y el 3 y el 4 se intercambian.
El anterior es el método de intercambio de punteros.

4. Cómo elegir los puntos de referencia

  1. Seleccione el primer elemento como punto de referencia
  2. Seleccione aleatoriamente un elemento como punto de referencia

5. Complejidad del tiempo

  La complejidad de tiempo promedio de quicksort es O (nlogn), y la complejidad de tiempo del peor de los casos es O (n ^ 2).

Cuando se selecciona el primer elemento como referencia, n elementos, cada elemento se atraviesa una vez, en este momento, la complejidad de tiempo es O (n ^ 2)

6.LeetCode

  215. Encuentre el k-ésimo elemento más grande en la matriz no ordenada (necesita encontrar el k-ésimo elemento más grande después de ordenar la matriz)

Entrada: [3,2,1,5,6,4] yk
salida: 5

class Solution:
    def findKthElement(self, nums, k):
        '''
        找到数组中第k个最大元素,
        快速排序每一轮确定一个位置,如果我们想要的位置的元素确定了,那么排序就结束了
        :param nums: 数组
        :param k: k
        :return: 返回第k个最大元素
        '''
        return self.quickSort(nums, k)

    def quickSort(self, nums, k):
        # 找到我们要寻找元素的位置
        k = len(nums) - k
        # 左右指针的位置
        left, right = 0, len(nums) - 1  # 0,4
        while left < right:
            # 进行分区操作,得到确定的位置,将确定的位置与k进行比较后,对子数据集进行分区操作
            j = self.partition(nums, left, right)
            if j == k:
                break
            elif j < k:
                left = j + 1
            else:
                right = j - 1
        # 跳出循环有两个条件:一种是j=k,一种是left=right,两种情况下均可满足j=k
        return nums[k]

    def partition(self, nums, left, right):
        '''
        分区操作—挖坑法,确定某个元素的位置
        :param nums: 数组
        :param left: 左指针
        :param right: 右指针
        :return: 返回确定元素的位置
        '''
        pivot = nums[left]
        # quickSort函数中也有left、right函数
        i, j = left, right
        # 跳出循环的条件是:i = j,此时,即为元素的位置
        while i < j:
            # 跳出条件是找到小于基准的元素nums[j]或i=j
            while i < j and nums[j] > pivot:
                j -= 1
            if i < j:
                nums[i] = nums[j]
                i += 1

            # 找到大于基准的元素nums[i]
            while i < j and nums[i] <= pivot:
                i += 1
            if i < j:
                nums[j] = nums[i]
                j -= 1
        # i = j时
        nums[i] = pivot
        return i


def main():
    nums = [3, 2, 1, 5, 6, 4]
    k = 2
    s = Solution()
    kth_element = s.findKthElement(nums, k)
    print('数组中第%d个最大元素为%d' % (k, kth_element))


if __name__ == '__main__':
    main()

El código se ha subido a https://github.com/Libra-1023/leetcode

Supongo que te gusta

Origin blog.csdn.net/weixin_46649052/article/details/114296843
Recomendado
Clasificación