Oferta de puntero de espada 49. Número feo && 264. Número feo II ●●

264. Buey número II

describir

Un número que contiene solo los factores primos 2, 3 y 5 se llama número feo (Número Feo).

Por lo general, 1 es el primer número feo, encuentre el enésimo número feo en orden ascendente.

ejemplo

Entrada: n = 10
Salida: 12
Explicación: [1, 2, 3, 4, 5, 6, 8, 9, 10, 12] es una secuencia que consta de los primeros 10 números feos.

respuesta

1. Pila superior pequeña

Para obtener el enésimo número feo de pequeño a grande, puede utilizar el montón mínimo para lograrlo.

Inicialmente el montón está vacío. Primero agregue el número 1 más pequeño y feo al montón.

Saque el elemento superior x del montón cada vez, que es el número feo más pequeño del montón . Dado que 2x, 3x, 5x también son números feos, agregue 2x, 3x, 5x al montón.

El enfoque anterior generará elementos duplicados en el montón. Para evitar elementos duplicados, puede utilizar el conjunto de hash para deduplicar y evitar agregar el mismo elemento al montón varias veces.

En el caso de excluir elementos duplicados, el elemento extraído del montón mínimo por enésima vez es el enésimo número feo.

  • Complejidad del tiempo: O ( n log ⁡ n ) O(n \log n)O ( n.iniciar sesiónnorte ) . Obtener el enésimo número feo requiere n ciclos, y cada ciclo necesitasacar1 elemento del montón mínimo yagregarcomo máximo 3 elementos al montón mínimo, por lo que la complejidad temporal de cada ciclo esO ( log ⁡ ( 3 n ) + 3 log ⁡ ( 3 n ) ) O(\log (3n) + 3 \log (3n))O ( iniciar sesión ( 3 norte )+3log ( 3 n )) , la complejidad del tiempo total esO ( n log ⁡ n ) O(n \log n )O ( n.iniciar sesiónnorte )
  • Complejidad espacial: O ( n ) O (n)O ( n ) . La complejidad del espacio depende principalmente del tamaño del montón mínimo y del conjunto de hash, y el tamaño del montón mínimo y del conjunto de hash no excederá 3n.
class Solution {
    
    
public:
    int nthUglyNumber(int n) {
    
    
        vector<int> factors = {
    
    2, 3, 5};		// 因子
        unordered_set<long> hash;				// 哈希
        priority_queue<long, vector<long>, greater<long>> heap;	// 小顶堆
        hash.insert(1L);
        heap.push(1L);
        int uglyn = 1;							
        for(int i = 1; i <= n; ++i){
    
    
            long top = heap.top();
            heap.pop();
            uglyn = (int)top;					// 第n个丑数
            for(int factor : factors){
    
    			// 堆中最小的丑数 * 因子2/3/5
                long next = top * factor;
                if(hash.count(next) == 0){
    
    
                    hash.insert(next);
                    heap.push(next);
                }
            }
        }
        return uglyn;
    }
};

2. Programación dinámica

El método 1 utiliza el montón mínimo, que almacenará números más feos por adelantado, y el proceso de mantener el montón mínimo también conduce a una gran complejidad temporal. La optimización
se puede realizar mediante programación dinámica .

Defina la matriz feos, donde uglys[i-1]representa el i-ésimo número feo.
uglys[0] = 1;

¿Cómo conseguir el resto de los números feos? Cada número feo tiene la posibilidad de multiplicarse por 2/3/5, defina tres punteros p2, p3, p5, lo que significa que el siguiente número feo es el valor mínimo
obtenido multiplicando el número feo señalado por los tres punteros por el correspondiente valor del factor primo . Inicialmente, los valores de los tres punteros son todos 0, y los punteros correspondientes serán +1 en cada ronda.

uglys[i] = min(min(num2, num3), num5);
Al realizar juicios de puntero y operaciones de movimiento, compare los resultados obtenidos por cada puntero para eliminar operaciones repetidas , como 5*2 y 2*5, luego p2 y p5 se mueven hacia la derecha.

  • Complejidad del tiempo: O (n). Es necesario calcular n elementos en la matriz, y el cálculo de cada elemento se puede completar en O (1) tiempo.
  • Complejidad espacial: O (n)
class Solution {
    
    
public:
    int nthUglyNumber(int n) {
    
    
        vector<int> uglys(n, 1);
        int p2 = 0, p3 = 0, p5 = 0;
        for(int i = 1; i < n; ++i){
    
    
            int num2 = uglys[p2]*2, num3 = uglys[p3]*3, num5 = uglys[p5]*5;
            uglys[i] = min(min(num2, num3), num5);
            if(uglys[i] == num2) ++p2;
            if(uglys[i] == num3) ++p3;
            if(uglys[i] == num5) ++p5;      // 不用else,去重,2*5 跟 5*2的情况,p2与p5++
        }
        return uglys[n-1];
    }
};

Supongo que te gusta

Origin blog.csdn.net/qq_19887221/article/details/126689247
Recomendado
Clasificación