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 n
reduce 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.
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-1
1 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 ( 1∗registro _ _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
递归时间复杂度 = 递归次数 * 每次操作的负载度