Comprensión recursiva y cálculo de la complejidad del tiempo.

1. Análisis de complejidad:

Se puede entender que la profundidad de la recursividad es la complejidad del espacio y la complejidad del tiempo es O (T * profundidad), donde T es la complejidad del tiempo de cada función recursiva y la profundidad es la profundidad de la recursividad.


#空间复杂度O(1)
def sum1_(n):
    res = 0
    for i in range(n+1):
        res+=i
    return res

#递归 空间复杂度O(n)
def sum2_(n):
    if n == 0:
        return 0
    return n+sum2_(n-1)

res1 = sum1_(n=10)
res2 = sum2_(n=10)
print('==res1:', res1)
print('==res2:', res2)

La complejidad temporal de la fórmula anterior también es O (1 * n) = O (n)

2. Ejemplos

1.Calcular x ^ n:


def pow(x, n):
    if n==0:
        return 1.
    t = pow(x, n//2)
    if n%2:
        return x*t*t
    else:
        return t*t

res = pow(2,3)
print('res:', res)

Profundidad de recursividad: logn, la complejidad de tiempo de cada función recursiva es O (1), por lo que la complejidad de tiempo es O (logn).

Complejidad del espacio: logn

2. Si hay n pasos, puede cruzar 1 paso o 2 t pasos cada vez ¿De cuántas formas hay para n pasos?

El primer paso es un paso o el primer paso son dos pasos, y el siguiente paso es similar, por lo que se trata de una recursividad.

Los n pasos son el método de caminar para agregar los n-1 pasos restantes después de caminar un paso, y el método de caminar de los n-2 pasos restantes después de caminar dos pasos.

f (n) = f (n-1) + f (n-2)

Condición de terminación: solo hay un paso para un paso y solo dos pasos para dos pasos.

f (1) = 1 , f (2) = 2

def fun(n):
    if(n == 1): return 1

    elif (n == 2): return 2

    else:
        return fun(n - 1) + fun(n - 2)

La complejidad temporal de cada función recursiva es O (1) y la complejidad espacial: O (2 ^ n), por lo que la complejidad temporal es O (2 ^ n).

Desventajas: desbordamiento de pila, cálculos repetidos, llamada de función que consume mucho tiempo, alta complejidad de espacio, etc.

Evite el desbordamiento de pila causado por la recursividad, agregue profundidad, no más desbordamiento si es mayor de 1000

depth=0
def fun(n):
    global depth
    depth+=1
    print('depth=',depth)
    if (depth>1000): return -1
    if(n == 1): return 1

    elif (n == 2): return 2

    else:
        return fun(n - 1) + fun(n - 2)
print(fun(3))

Hay muchos cálculos dobles:

Idea de optimización 1: 

Recurrencia, de abajo hacia arriba:

class Solution:
    def numWays(self, n: int) -> int:
        a,b=1,1
        for i in range(n):
            a,b = a+b,a
        return b

Idea 2: Almacene el valor calculado para el juicio:


def fun(n,arr):
    if(n == 1): return 1
    elif (n == 2): return 2
    else:
        if arr[n]!=-1:
            return arr[n]
        else:
            arr[n] = fun(n - 1,arr) + fun(n - 2,arr)
            return arr[n]
n = 6
arr = [-1]*(n+1)
res= fun(n=n, arr=arr)
print('==res:', res)

3. Realice recursivamente la permutación completa:

def swap(a, p, i):
    a[p], a[i] = a[i], a[p]
    return a

#取第一个数,剩下的做排序,边界条件是开始索引p==终止索引q
def main(a, p, q):
    res = []

    def permute(a, p, q):
        if p == q:
            res.append(a.copy())
            print('res:', res)
        else:
            for i in range(p, q, 1):
                swap(a, p, i)
                permute(a, p+1, q)
                print('a:', a.copy())
                swap(a, p, i)#a还原成原顺序,比如2开头的结束了是2 1 3 需要还原成1 2 3 在吧3放在开头在排序
                print('==a:', a.copy())


    permute(a, p, q)
    print('==res:', res)


#
# a = [1]
# a = [1, 2]
a=[1, 2, 3]
main(a, 0, len(a))


class Solution:
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """

        def backtrack(first=0):
            # 所有数都填完了
            if first == n:
                res.append(nums.copy())
            for i in range(first, n):
                # 动态维护数组
                nums[first], nums[i] = nums[i], nums[first]
                # 继续递归填下一个数
                backtrack(first + 1)
                # 撤销操作
                nums[first], nums[i] = nums[i], nums[first]

        n = len(nums)
        res = []
        backtrack()
        return res


a = [1, 2, 3]
sol = Solution()
res = sol.permute(a)
print('===res:', res)

4. Realice de forma recursiva potencia rápida

Pregunta: Encuentre el valor de a módulo p elevado a b

#a^b%p
def a_b_p(a,b,p):
    if b == 0:
        return 1
    elif b%2 == 1:#b是奇数
        return a*a_b_p(a, b-1, p)%p
    else:#b是偶数
        temp = a_b_p(a, b//2, p)
        return (temp*temp)%p

res = a_b_p(3,3,4)
print('==res:', res)

5. Implementar de forma recursiva la Torre Han Luo


#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
using namespace std;
//a--from b--temp c--to
void hano(int n, char a, char b, char c);
int main(){
    hano(3, 'a', 'b', 'c');
    return 0;
    }
//a--from b--temp c--to
void hano(int n,char a, char b, char c){
    if(n==1){
        cout<<a<<"-->"<<c<<endl;
    }
    else{
        hano(n-1, a, c, b);//c为temp,a上面的n-1给b
        hano(1, a, b, c);//b为temp,a上面的1给c
        hano(n-1, b, a, c);//a为temp,b上面的n-1给c
    }
}

Agregue el número de placa:

La placa es de 1 an de arriba a abajo

#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
using namespace std;
//a--from b--temp c--to
void hano(int top, int n, char a, char b, char c);
int main(){
    hano(1, 3, 'a', 'b', 'c');
    return 0;
    }
//a--from b--temp c--to
void hano(int top, int n,char a, char b, char c){
    if(n==1){
        cout<<"盘子"<<top<<a<<"-->"<<c<<endl;
    }
    else{
        hano(top, n-1, a, c, b);//c为temp,a上面的n-1给b
        hano(top + n - 1, 1, a, b, c);//b为temp,a上面的1给c
        hano(top, n-1, b, a, c);//a为temp,b上面的n-1给c
    }
}

Supongo que te gusta

Origin blog.csdn.net/fanzonghao/article/details/83038940
Recomendado
Clasificación