[Algoritmo] Mire el cálculo recursivo de la complejidad del tiempo a partir de la n-ésima potencia de x

Mirando el cálculo recursivo de la complejidad del tiempo a partir de la n-ésima potencia de x

1. Bucle

La solución más fácil a este problema es usar un bucle

int pow1(int x,int n)
{
    
    
	int result = 1;
    for(int i=0;i<n;i++)
    {
    
    
        result*=x;
    }
    return result;
}

La complejidad de tiempo del algoritmo anterior es O(N), pero aún no es ideal. En este momento intenta usar el algoritmo recursivo

2. Recursión 1

int pow2(int x,int n)
{
    
    
	if(n==0)// x^0 = 1
        return 1;
    return pow2(x,n-1)*x;
}

Utilizando el método de cálculo de la complejidad del tiempo de la función recursiva anterior, el número de llamadas recursivas de esta función se nreduce desde 0 hasta 0, es decir, n veces. En cada recursión se requiere un cálculo de multiplicación, es decir,O(1)

La complejidad de tiempo final O(n*1) = O(n)es la misma que el código que escribimos con bucles

3. Recursión 2, árbol binario

int pow3(int x,int n)
{
    
    
	if(n==0)// x^0 = 1
        return 1;
    if(n==1)// 减少一次递归
        return x;
    if(n%2==1)// 奇数
    	return pow3(x,n/2)*pow3(x,n/2)*x;
    // 偶数方
    return pow3(x,n/2)*pow3(x,n/2);
}

Finalmente, la operación de potencia se abstrae en un árbol binario.

imagen-20230419102447146

El número total de recursiones, es decir, el número de nodos en el árbol binario. Podemos calcular el número de nodos en este árbol binario completo como2^4-1 = 15

Entonces, un total de 15 veces de recursión, cada operación sigue siendo una multiplicación,O(1)

Así que la complejidad del tiempo final es

递归次数 = 满二叉树节点个数 = 2^m -1
m = 二叉树层数(从1开始)= log(n)

Se puede calcular la incorporación, el número total final de nodos en el árbol binario es n-11 y la complejidad del tiempo sigue siendo O(N). Esto muestra que nuestro algoritmo no es lo suficientemente bueno.

Puntos de conocimiento relacionados con el árbol binario https://blog.musnow.top/posts/4161984418/

4. Recursión 3

Si observa la tercera función, puede ver que hay 2 llamadas recursivas independientemente de los números pares o impares, pero ambas llamadas recursivas son exactamente iguales

pow3(x,n/2)*pow3(x,n/2);

En otras palabras, podemos llamar recursivamente una vez primero, guardar el resultado y calcular de nuevo.

int pow4(int x,int n)
{
    
    
	if(n==0)// x^0 = 1
        return 1;
    if(n==1)// 减少一次递归
        return x;
    int tmp = pow3(x,n/2);
    if(n%2==1)// 奇数
    	return tmp*tmp*x;
    // 偶数方
    return tmp*tmp;
}

En este momento, solo se llama a una recursión en la función.Después de cada recursión, los datos se dividen por 2, por lo que el total es log 2 (n) veces

Cada recursión sigue siendo una operación de multiplicación, y la complejidad del tiempo es O(1)
O ( 1 ∗ log 2 n ) O(1*log_2n)O ( 1registro _ _2n )
La complejidad temporal resultante esO(logN)!

El fin

Este es el algoritmo con menor complejidad de tiempo que necesitamos, y también revisamos el método de cálculo de complejidad de tiempo de llamadas recursivas

递归时间复杂度 = 递归次数 * 每次操作的负载度

Supongo que te gusta

Origin blog.csdn.net/muxuen/article/details/130334304
Recomendado
Clasificación