Algoritmo de la opinión: Una reflexión desde la escalera número de Fibonacci problema de forma recursiva, para lograr la programación dinámica

Problemas conducen:
No.70 leetcode

Si no se inicia cuando tal práctica:

Considere
no funciona, entonces considere lo siguiente: 1. La violencia puede resolver
2. Debido a que el problema es más complicado luego comparar para mirar a la situación básica de inducción matemática se resume en general, se considera
3. hallazgo lógica para encontrar la más reciente iteración de sub-problemas , es decir, para encontrar el problema en parte repetida
- considere el uso de la recursividad o programación dinámica

recursividad

1. El O recursiva estúpida más común (2 ^ n) y puede conducir a StackOverflow

// 方法一:直接递归  
// 但是这道题有点和斐波那契数列稍稍不符合的地方是 f0=0 而数列中f0=1;
class Solution {
    public int climbStairs(int n) {
          
         if(n == 0) { //不同处 f0=0,它有点点不符合斐波那契数列的思想 而数列中f0=1;
             return 0;
         }   
         if(n == 1) {
            return 1;
         }
         if(n == 2) {
          	return 2;
         }
            return  climbStairs(n-2) + climbStairs(n-1); 
         }  
    }

2. plus una matriz de tampón recursiva (predecesores árboles descendientes enfríen LOL)

//这个方法是可以的!! 但是只是适用于在输入44之前的数
// 方法二:记忆化递归 有缓存的思想 创一个数组 每次把递归的结果记录下来 方便下一次递归使用
//每当函数再次被递归调用时,我们就直接从 memo 数组返回结果。
// 但是这道题有点和斐波那契数列稍稍不符合的地方是 f0=0 而数列中f0=1;
class Solution {
    public int climbStairs(int n) {
         int memo[] = new int[n + 1];//防止递归时 溢出
         if(n == 0) { //不同处 f0=0,它有点点不符合斐波那契数列的思想 而数列中f0=1;
             memo[0] = 0;
             return 0;
         }   
         if(n == 1) {
             memo[1] = 1;
             return 1;
         }
         if(n == 2) {
             memo[2] = 2;
             return 2;
         }
         //接下来 和普通递归不同处是 每次先找缓存里面找我需要的递归式 是否已经在上一步算出来并且缓存了
         if(memo[n] != 0) { //因为java数组默认全部填0  那么我这里如果判断n这个位置不是0 说明已经缓存过 
            return memo[n]; //那就返回即可
         } else { //说明之前没缓存 需要缓存 给后面用 (前人栽树后人乘凉LOL)
            int rst = climbStairs(n-2) + climbStairs(n-1); 
            memo[n] = rst;
            return rst; 
         }  
    }
}

3. El 2plus método utilizando hashmap recursivo almacenado en caché

//这个方法也是可以的!! 但是只是适用于在输入44之前的数
// 方法三:记忆化递归plus 有缓存的思想 创一个数组 每次把递归的结果记录下来 方便下一次递归使用
//每当函数再次被递归调用时,和前一种方法的存储不同,前一种我们是从 数组memo[] 返回结果。 而现在可以使用hashmap(好处是使用它内部的查询优化)
// 但是这道题有点和斐波那契数列稍稍不符合的地方是 f0=0 而数列中f0=1;
class Solution {
    public int climbStairs(int n) {
        //  int memo[] = new int[n + 1];//防止递归时 溢出 不用它了 用hashmap
      Map<Integer, Integer> memo = new HashMap<>();
         if(n == 0) { //不同处 f0=0,它有点点不符合斐波那契数列的思想 而数列中f0=1;
             memo.put(0,0);
             return 0;
         }   
         if(n == 1) {
             memo.put(1,1);
             return 1;
         }
         if(n == 2) {
             memo.put(2,2);
             return 2;
         }
         //接下来 和普通递归不同处是 每次先找缓存里面找我需要的递归式 是否已经在上一步算出来并且缓存了
         if(null != memo.get(n)) { //能取到值 说明已经缓存过 
            return memo.get(n); //那就返回即可
         } else { //说明之前没缓存 需要缓存 给后面用 (前人栽树后人乘凉LOL)
            int rst = climbStairs(n-2) + climbStairs(n-1); 
            memo.put(n,rst);
            return rst; 
         }  
    }
}

4. Método cuatro: programación dinámica (de abajo hacia arriba de programación dinámica) o crear una matriz de los resultados por (soluciones sub-problema) programación grabada problema con un padre convenientemente
, de hecho, hay un método memorando de programación dinámica (de de arriba hacia abajo)

class Solution {
    public int climbStairs(int n) {
        // int dp[] = new int[n+1];//当n取1 这就会报错 所以可以再开大点
        int dp[] = new int[n+2]; 
        if (n == 0) {
            return 0;
        }
        // if (n == 1) {
        //     return 1;
        // }
        // if (n == 2) {
        //     return 2;
        // } //实际可以用下一句代替 因为程序最好单一出口 或者少出口 但是写上的话 易读性更好
        dp[1] = 1;
        dp[2] = 2;
        for(int i = 3; i <= n; i++) {
            dp[i] = dp[i-2] + dp[i-1];
        }
        return dp[n];
    }
}

// / 方法四:动态规划 还是 创一个数组 每次把规划的结果(子问题的解)记录下来 方便下一次父问题使用
 // 但是这道题有点和斐波那契数列稍稍不符合的地方是 f0=0 而数列中f0=1;

La programación dinámica más (también conocido como Fibonacci) no requiere cada matriz no requiere los resultados (solución del problema de los niños) grabados la planificación de
cada sub-problemas existe sólo durante los tres últimos valores puede ser porque que la solución es una solución del problema de la transformación dinámica de los padres de las condiciones que cambia constantemente por lo que la cuenta atrás para el segundo tercer número sin duda puede ser una solución del problema de los niños durar varios

//复习前一天:
// 方法五: 动态规划 但不使用循环 无需记录过程中的数 但是只需要记住最后的三个数即可 因为过程中每次子问题的解是动态变换的  也就是说作为解父问题的条件他是不断变换的 那么到了倒数的第二个第三个数 肯定是可以成为最后一个属的子问题的解 
class Solution {
    public int climbStairs(int n) {
        int rst = 0;
        int f1 = 1;
        int f2 = 2;
        if(n == 0) { //不同处 f0=0,它有点点不符合斐波那契数列的思想 而数列中f0=1;  
             return 0;
         }   
         if(n == 1) {
            return 1;
         }
         if(n == 2) {
          	return 2;
         }
         for(int i = 3; i <= n; i++) {
             rst = f2 + f1;
             f1 = f2;
             f2 = rst;
         }   
         return  rst; 
         }          
    }

¿Cuáles son las diferencias "recursión" y "iterativo" tienen?

Publicado 81 artículos originales · ganado elogios 19 · vistas 3603

Supongo que te gusta

Origin blog.csdn.net/c22cxz/article/details/105030128
Recomendado
Clasificación