剑指offer(C++)-JZ69:跳台阶(算法-动态规划)

简介: 剑指offer(C++)-JZ69:跳台阶(算法-动态规划)

题目描述:

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

数据范围:1≤n≤40

要求:时间复杂度:O(n) ,空间复杂度: O(1)

示例:

输入:

2


返回值:

2


说明:

青蛙要跳上两级台阶有两种跳法,分别是:先跳一级,再跳一级或者直接跳两级。因此答案为2

解题思路:

本题考察算法-动态规划算法的使用。用四种逐优的解法,来一步步发现动态规划算法的优势。


解法一:递归法。青蛙可以一次跳一阶也可以跳两阶,假设跳到n阶时的方案数为F(n),那么跳到n-1阶的方案数再加一就能跳到n阶,跳到n-2阶的方案数再加二也能跳到n阶,则跳到n阶的方案数是它们的和,即F(n)=F(n-1)+F(n-2),初始条件n小于等于1时,方案数为1,用递归很容易实现。时间复杂度O(2^n),因为每次调用jumpFloor,都要继续调用两次jumpFloor,这个复杂度是很高的;空间复杂度是递归栈空间,递归次数很大时,空间复杂度也是很高的。该方法虽然很容易写且理解,但是最不实用。


解法二:改进递归法。在解法一中不难发现,jumpFloor在执行过程中进行了大量的重复工作,比如计算F(5)时计算过F(4)和F(3),但计算F(6)时又计算了多遍,那如果用数组存好F(x)的数值,只要计算一次就足够了,再次调用只需要读取数组数据即可。这样时间复杂度降到了O(n),空间复杂度变为O(n)和递归栈空间。


解法三:动态规划。动态规划是在计算过程中,不断分析每一步的最优解,当进行到最后一步时,结果自然得出。如果说递归法是从后往前,那么动态规划就是从前往后。节省了递归栈空间。本题目简单,用一个循环即可完成,时间复杂度和空间复杂度均为O(n)。


解法四:改进的动态规划。解法三中空间复杂度还是太高,考虑到我们只需要求最终的结果,所以中间过程的数据并不需要保存下来,那么可以优化掉数组,用变量来动态存储F(n-1)和F(n-2)即可,时间复杂度为O(n),空间复杂度为O(1)。

测试代码:

解法一:递归法

class Solution {
  public:
    int jumpFloor(int number) {
        if (number <= 1)
            return 1;
        return jumpFloor(number-1)+jumpFloor(number-2);
    }
};

解法二:改进递归法

class Solution {
  public:
    int data[100]{0};
    int jumpFloor(int number) {
        if (number <= 1)
            return 1;
        if(data[number]>0)
            return data[number];
        else
            data[number]=jumpFloor(number-1)+jumpFloor(number-2);
        return data[number];
    }
};

解法三:动态规划

class Solution {
  public:
    int data[100]{0};
    int jumpFloor(int number) {
        data[0]=1;
        data[1]=1;
        for(int i=2;i<=number;++i)
            data[i]=data[i-1]+data[i-2];
        return data[number];
    }
};

解法四:改进的动态规划

class Solution {
  public:
    int jumpFloor(int number) {
        int a=1,b=1,c=1;
        for(int i=2;i<=number;++i)
        {
            c=a+b;
            a=b;
            b=c;
        }
        return c;
    }
};


相关文章
|
7天前
|
存储 算法 Java
算法系列之动态规划
动态规划(Dynamic Programming,简称DP)是一种用于解决复杂问题的算法设计技术。它通过将问题分解为更小的子问题,并存储这些子问题的解来避免重复计算,从而提高算法的效率。
21 4
算法系列之动态规划
|
18天前
|
存储 监控 算法
员工屏幕监控系统之 C++ 图像差分算法
在现代企业管理中,员工屏幕监控系统至关重要。本文探讨了其中常用的图像差分算法,该算法通过比较相邻两帧图像的像素差异,检测屏幕内容变化,如应用程序切换等。文中提供了C++实现代码,并介绍了其在实时监控、异常行为检测和数据压缩等方面的应用,展示了其实现简单、效率高的特点。
40 15
|
18天前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
46 12
|
9天前
|
存储 监控 算法
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
在数字化办公时代,公司监控上网软件成为企业管理网络资源和保障信息安全的关键工具。本文深入剖析C++中的链表数据结构及其在该软件中的应用。链表通过节点存储网络访问记录,具备高效插入、删除操作及节省内存的优势,助力企业实时追踪员工上网行为,提升运营效率并降低安全风险。示例代码展示了如何用C++实现链表记录上网行为,并模拟发送至服务器。链表为公司监控上网软件提供了灵活高效的数据管理方式,但实际开发还需考虑安全性、隐私保护等多方面因素。
15 0
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
|
2月前
|
负载均衡 算法 安全
探秘:基于 C++ 的局域网电脑控制软件自适应指令分发算法
在现代企业信息化架构中,局域网电脑控制软件如同“指挥官”,通过自适应指令分发算法动态调整指令发送节奏与数据量,确保不同性能的终端设备高效运行。基于C++语言,利用套接字实现稳定连接和线程同步管理,结合实时状态反馈,优化指令分发策略,提升整体管控效率,保障网络稳定,助力数字化办公。
69 19
|
15天前
|
算法 安全 调度
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
|
15天前
|
机器学习/深度学习 算法 测试技术
【动态规划篇】01 背包的逆袭:如何用算法装满你的 “财富背包”
【动态规划篇】01 背包的逆袭:如何用算法装满你的 “财富背包”
|
2月前
|
算法 Java C++
【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
本文介绍了经典的0/1背包问题及其动态规划解法。
58 5
|
2月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
55 2
|
3月前
|
存储 算法 安全
基于红黑树的局域网上网行为控制C++ 算法解析
在当今网络环境中,局域网上网行为控制对企业和学校至关重要。本文探讨了一种基于红黑树数据结构的高效算法,用于管理用户的上网行为,如IP地址、上网时长、访问网站类别和流量使用情况。通过红黑树的自平衡特性,确保了高效的查找、插入和删除操作。文中提供了C++代码示例,展示了如何实现该算法,并强调其在网络管理中的应用价值。