Preguntas de cepillado de estructura de datos: Día 16 (Básico)

 

Tabla de contenido

1. Clasificación de colores

1, puntero único

Análisis de Complejidad

2, doble puntero

Análisis de Complejidad

En segundo lugar, el intervalo de fusión

1. Ordenar

tren de pensamiento

Mira la solución:

1. Clasificación de colores

75. Clasificación de colores - LeetCode https://leetcode.cn/problems/sort-colors/?plan=data-structures&plan_progress=zz5yyb3

1, puntero único

Podemos considerar hacer dos pasadas sobre la matriz. En el primer paso, cambiamos todos los ceros de la matriz a la cabeza de la matriz. En el segundo paso, intercambiamos todos los 1 en la matriz después de los 0 en la cabeza. En este punto, todos los 2 aparecen al final de la matriz y hemos terminado de ordenar.

Específicamente, usamos un puntero ptr para representar el rango de la "cabeza". Un número entero se almacena en ptr, lo que indica que la matriz nums desde la posición 0 hasta la posición ptr−1 pertenece a la "cabeza". El valor inicial de ptr es 0, lo que significa que no hay ningún número en la "cabeza".

En el primer recorrido, recorremos toda la matriz de izquierda a derecha. Si encontramos 0, entonces necesitamos intercambiar 0 con el elemento en la posición de "cabeza" y expandir la "cabeza" hacia atrás en una posición. Una vez que se completa el recorrido, todos los 0 se intercambian al rango de "cabeza", y "cabeza" contiene solo 0.

En el segundo recorrido, comenzamos desde la "cabeza" y recorremos toda la matriz de izquierda a derecha. Si se encuentra 1, entonces necesitamos intercambiar 1 con el elemento en la posición "cabeza" y reemplazar la "cabeza" Expandir hacia atrás una posición. Una vez que finaliza el recorrido, todos los 1 se intercambian al rango de la "cabeza", y todos están después de 0. En este momento, 2 solo aparece fuera de la "cabeza", por lo que la clasificación está completa.

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n = nums.size();
        int ptr = 0;
        for (int i = 0; i < n; ++i) {
            if (nums[i] == 0) {
                swap(nums[i], nums[ptr]);
                ++ptr;
            }
        }
        for (int i = ptr; i < n; ++i) {
            if (nums[i] == 1) {
                swap(nums[i], nums[ptr]);
                ++ptr;
            }
        }
    }
};

Análisis de Complejidad

  • Complejidad temporal: O(n), donde nn es la longitud del arreglo \textit{nums}nums.

  • Complejidad espacial: O(1).

2, doble puntero

El método 1 requiere dos recorridos, entonces, ¿podemos usar solo un recorrido? Podemos usar un puntero adicional, es decir, usar dos punteros para intercambiar 0 y 1 respectivamente.

Específicamente, usamos el puntero p_0 para intercambiar 0, p_1 para intercambiar 1, y el valor inicial es 0. A medida que recorremos toda la matriz de izquierda a derecha:

Si se encuentra 1, cámbielo por nums[p 1 ] y mueva p_1 hacia atrás una posición, que es lo mismo que el método uno;

Si se encuentra 0, se intercambia con [p_0]nums[p] y p_0 se desplaza hacia atrás una posición. ¿Es esto lo correcto? Podemos notar que dado que los 0 consecutivos son seguidos por 1 consecutivos, si intercambiamos 0 con números [p 0], podríamos intercambiar un 1. Cuando p_0 < p_1, hemos puesto unos 1 en la cabeza continuamente, y en este momento, debemos intercambiar un 1, resultando una respuesta incorrecta. Por lo tanto, si p_0 < p_1, entonces necesitamos intercambiar nums[i] con nums[p 1], donde i es la posición actual atravesada, después del primer intercambio, el valor de nums[i] es 1, necesitamos poner este 1 al final de la "cabeza". Al final, necesitamos mover p_0 y p_1 hacia atrás una posición, no solo p_0 una posición, sin importar si p_0 < p_1 o no.

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n = nums.size();
        int p0 = 0, p1 = 0;
        for (int i = 0; i < n; ++i) {
            if (nums[i] == 1) {
                swap(nums[i], nums[p1]);
                ++p1;
            } else if (nums[i] == 0) {
                swap(nums[i], nums[p0]);
                if (p0 < p1) {
                    swap(nums[i], nums[p1]);
                }
                ++p0;
                ++p1;
            }
        }
    }
};

Análisis de Complejidad

  • Complejidad temporal: O(n), donde nn es la longitud del arreglo \textit{nums}nums.

  • Complejidad espacial: O(1).

En segundo lugar, el intervalo de fusión

56. Combinar intervalos - LeetCode https://leetcode.cn/problems/merge-intervals/?plan=data-structures&plan_progress=zz5yyb3

1. Ordenar

tren de pensamiento

Si ordenamos según el extremo izquierdo del intervalo, entonces en la lista ordenada, los intervalos que se pueden combinar deben ser continuos. Como se muestra en la figura a continuación, los intervalos marcados en azul, amarillo y verde se pueden fusionar en un intervalo grande respectivamente, y son continuos en la lista ordenada:

#define MAX_LEN 100000            // the amount of buckets

class MyHashMap {
private:
    vector<pair<int, int>> map[MAX_LEN];     
    
    /** 定义散列函数返回存储数据的下标 */
    int getIndex(int key) {
        return key % MAX_LEN;
    }
    /* 查找数据在哈希表中的位置 */
    int getPos(int key, int index) {
        for (int i = 0; i < map[index].size(); ++i) {
            if (map[index][i].first == key) {
                return i;
            }
        }
        return -1;
    }
    
public:
    
    MyHashMap() {   
    }
    /* 插入一个键值对key, value。如果key存在于映射中,则更新其对应的值value */
    void put(int key, int value) {
        int index = getIndex(key);
        int pos = getPos(key, index);
        if (pos < 0) {
            map[index].push_back(make_pair(key, value));
        } else {
            map[index][pos].second = value;
        }
    }
    /* 返回特定的key所映射的value;如果映射中不包含key的映射,返回 -1  */
    int get(int key) {
        int index = getIndex(key);
        int pos = getPos(key, index);
        if (pos < 0) {
            return -1;
        } else {
            return map[index][pos].second;
        }
    }
    
    /** 如果映射中存在key的映射,则移除key和它所对应的value  */
    void remove(int key) {
        int index = getIndex(key);
        int pos = getPos(key, index);
        if (pos >= 0) {
            map[index].erase(map[index].begin() + pos);
        }
    }
};

Mira la solución:

706. Design Hash Map (Preguntas básicas detalladas del código C++) - Design Hash Map - LeetCode https://leetcode.cn/problems/design-hashmap/solution/by-nehzil-bhd2/

Supongo que te gusta

Origin blog.csdn.net/m0_63309778/article/details/127059963
Recomendado
Clasificación