• 【Leetcode】爬楼梯


    问题:

    爬n阶楼梯,每次只能走1阶或者2阶,计算有多少种走法。

    暴力计算+记忆化递归。

    从位置 i 出发,每次走1阶或者2阶台阶,记录从位置 i 出发到目标 n 所有的走法数量,memoA[i] 。记录的数据可以重复使用,避免冗余计算。

    时间复杂度:O(n)。每次计算从 i 位置出发到终点 n 的走法,共计算 n 次,即树形递归的大小为n。

    空间复杂度:O(n)。使用了长度为 n 的数组。

    clock_t start1, end1;
    
    class Solution {
    public:
        int climbStairs(int n) {
            
            int memo[n+1] = {0};
            
            start1 = clock();
            int result = climb_stairs(0, n, memo);
            end1 = clock();
            
            cout << "cost time = " << (double)(end1 - start1) / CLOCKS_PER_SEC << endl;
            
            return result;
        }
        
        int climb_stairs(int i, int nums, int memoA[]) {
            
            if (i > nums)
                return 0;
            
            if (i == nums)
                return 1;
            
            if (memoA[i] > 0)
                return memoA[i];
            
            memoA[i] = climb_stairs(i+1, nums, memoA) + climb_stairs(i+2, nums, memoA);        
            
            return memoA[i];
        }
    };

    动态规划

    动态规划的关键步骤在于构建递归函数。由于第n级阶梯可由第n-1级(跨一步)和第n-2级(跨两步)到达。记 f(n) 为到达第n级阶梯的方案数量,则有递归函数 f(n) = f(n-1)+f(n-2).

    1)动态规划第一种实现方法:

    时间复杂度:O(2^n)。其运算过程就是一个完全二叉树的展开,共有 2^(n-2)+1 个节点,即递归运算了 2^(n-2)+1 次。

    空间复杂度:O(n)。递归深度达到n层。

    class Solution {
    public:
        int climbStairs(int n) {
            if (n == 1)
                return 1;
            if (n == 2)
                return 2;
            
            int sumMethod = climbStairs(n-1) + climbStairs(n-2);
            
            return sumMethod;
        }
    };

    2)动态规划第二种实现方法:

    时间复杂度:O(n)

    空间复杂度:O(n)

    class Solution {
    public:
        int climbStairs(int n) {
            if (n == 1)
                return 1;
            
            int memo[n+1] = {0};
            memo[1] = 1;
            memo[2] = 2;
            
            for(int i = 3; i <= n; ++i) {
                memo[i] = memo[i-1] + memo[i-2];
            }
            
            return memo[n];        
        }
    };

    斐波那契数

    将动态规划的第二种实现方法进行修改。第一项为1,第二项为2,斐波那契数的计算公式如下:

    fib(n) = fib(n-1)+fib(n-2)。

    时间复杂度:O(n)

    空间复杂度:O(1)

    还存在时间复杂度为 O(log(n))算法,其核心思想为直接找到第n个斐波那契数,而非进行遍历计算。

    这就是算法的魅力。从暴力求解开始,逐步优化算法流程,砍掉冗余的计算步骤,尽可能去除遍历步骤。最终达到提升时间复杂度和空间复杂度的目的。

  • 相关阅读:
    函数模板的局限性级解决方法(第三代具体化)
    模板实现机制
    函数模板与普通函数的区别以及调用规则
    函数模板基本用法及泛型
    向上类型转换和向下类型转换
    虚析构和纯虚析构
    纯虚函数和抽象类
    多态原理
    静态联编和动态联编即多态的概念
    虚基类的内部工作原理
  • 原文地址:https://www.cnblogs.com/gdut-gordon/p/11623662.html
Copyright © 2020-2023  润新知