75. Dos métodos de clasificación de colores, 2 + 1 puntero y tres punteros, análisis del principio de algoritmo

75. Clasificación de colores

Dada una matriz de n elementos que contengan rojo, blanco y azul, ordénelos en su lugar para que los elementos del mismo color estén adyacentes y dispuestos en el orden de rojo, blanco y azul.

En esta pregunta, usamos los números enteros 0, 1 y 2 para representar el rojo, el blanco y el azul, respectivamente.

Nota:
No puede utilizar la función de clasificación en el código base para resolver este problema.

Ejemplo:

Entrada: [2,0,2,1,1,0]
Salida: [0,0,1,1,2,2]
Avanzado:

Una solución intuitiva es utilizar un algoritmo de escaneo de dos pasos para contar y clasificar.
Primero, calcule iterativamente el número de elementos 0, 1 y 2, y luego vuelva a escribir la matriz actual de acuerdo con el orden de 0, 1 y 2.
¿Puede pensar en un algoritmo de escaneo de un solo paso que use solo espacio constante?

Solución 1: Primero doble puntero, introduzca el tercer puntero cuando no se mueva

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int len = nums.size();
        if (len < 2)
            return;
        
        int left = 0, right = len-1;
        while (left < right) {
            if (nums[left] == 0) {                              //先两边符合条件的数值
                ++left;
                continue;
            } else if (nums[right] == 2) {
                --right;
                continue;
            }

            if (nums[left] == 2) {
                swap(nums[left], nums[right]);
                --right;
            } else if (nums[right] == 0) {
                swap(nums[left], nums[right]);
                ++left;
            } else if (nums[left] == 1 && nums[right] == 1) {  //双指针寸步难行
                int mid = left+1;                              //引入第三指针
                while (mid < right && nums[mid] == 1)          //找中间不符合条件的数值
                    ++mid;
                if (mid == right)
                    return;

                if (nums[mid] == 0) {
                    swap(nums[left], nums[mid]);
                    ++left;
                } else {
                    swap(nums[right], nums[mid]);
                    --right;
                }
            }
        }
    }
};

          La idea de este método es relativamente simple y el valor es relativamente estable . Los 2 últimos están siempre en el último lado y no se cambiarán. Y solo cuando sea necesario (el límite del intervalo es la 1 en punto) introduzca el tercer puntero auxiliar, sin mantener los tres punteros todo el tiempo, la operación es relativamente simple y el pensamiento es relativamente claro.

          Cuando hay 1 a la derecha y muchos 1 a la izquierda, con un poco de 0/2 en el medio, el algoritmo introducirá con frecuencia el tercer puntero, y el tercer puntero atravesará repetidamente desde el límite izquierdo 1 al derecho.

Solución 2: tres punteros directos

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int len = nums.size();
        if (len < 2)
            return;
        
        int left = 0, cur = 0, right = len-1;
        while (cur <= right) {                    //需要同步跟新left, 所以有等号
            if (nums[cur] == 0) {
                if (left != cur)
                    swap(nums[left], nums[cur]);
                ++left;
                ++cur;                            //从前往后,一步为0可以往下走
            } else if (nums[cur] == 2) {
                if (right != cur)
                    swap(nums[right], nums[cur]);
                --right;
                //++cur;                          //cur不能往前走,从后换到当前的值不知道是0/1/2
            } else {
                ++cur;                            //当cur指的数为1时,会落下left指向第一个为1的数
            }
        }
    }
};

          Esta solución siempre mantiene tres punteros y el algoritmo no tiene estabilidad. Incluso si el valor al final cumple con las condiciones, se cambiará a cur, y luego el 2 encontrado al principio se cambiará al final La estabilidad del valor es equivalente a una inversión de orden.

          El algoritmo es peor cuando la matriz original tiene 2 al principio y los últimos 2 están aproximadamente en orden.

Supongo que te gusta

Origin blog.csdn.net/sy_123a/article/details/109124139
Recomendado
Clasificación