动态规划-爬楼梯问题java实现
最近开始看算法导论,研究了一下动态规划,下面就开始直入主题开始记录近期看的第一个知识点动态规划。提起动态规划就不得不提几个动态规划的金典问题爬楼梯、国王金矿、背包问题。今天就仔细分析一下爬楼梯问题。
列子 问:有一个高度为10级台阶的楼梯,从下往上走,每一次向上跨一个台阶只能是一个台阶或者两个台阶,要求用程序求出来一共有多少种算法?
思考:如果每次都跨一个台阶 则为 1+1+1+1+1+1+1+1+1+1这种方式 、如果每次都跨两个台阶则为2+2+2+2+2+2......很多很多种,最简单暴力的算法就是写个多种循环递归调用输出所有的可行的方法,但是这种方法时效率最低的时间复杂度成指数形式递增。现在我们就开始考虑用动态规划的思路来思考这个问题,动态规划的思路就是将问题拆分、分治。
首先将问题先考虑爬楼梯的问题执行到最后一步了,只差一步就可以结束这个请款下的问题,在这个时候只有两种可能了一、从第9阶楼梯跨一步到达10阶和从第8阶一次性跨两个台阶到达10阶。假设到达第9阶台阶的方法为a种,到达第8阶的方法为b种 则到达第10阶的方法则为a+b,ok这个时候我们简写 到10阶台阶的方法为F(10),则F(10) = F(9)+F(8),然后同理继续拆分 F(9)=F(8)+F(7),F(8)=F(7)+F(6),拆分到最后当台阶只剩下1阶和二阶的时候很容易得到一个常量 F(1)=1,F(2)=2,由此可得一个公式:
F(n) = F(n-1)+F(n-2) (n>=3)
这个时候我们就得到了用到了动态规划的的概念 F(9)和F(8)是F(10)的最优子结构,F(1)=1,F(2)=2就是动态规划所谓的问题的边界,而上面所得到的公式就是状态转移方程,好了到现在为止 已近理清了我们的思路现在就要开始考虑如何解问题了,代码采用java编写
方法一、
public int getClimblingWays(int n){
if ( n<1 ) return 0;
if (n == 1)return 1;
if (n == 2)return 2;
return getClimblingWays(n-1)+getClimblingWays(n-2);
}
当然这个方法可以解决这个问题但是我们也要考虑 这个是不是运行了是很重复的计算,下面是一张所有计算节点的图
这个算法的时间复杂度是一个是一个二叉树,每一个节点都去过去进行计算即使已经计算过了 ,我们可不可以做个缓存记住已近计算好的结果呢?这里我们就引出了第二种方法
方法二、备忘录算法
public int getClimblingWaysWithCache(int n, Map<Integer,Integer> map){
if ( n<1 ) return 0;
if (n == 1)return 1;
if (n == 2)return 2;
if (map.containsKey(n)){
return map.get(n);
}else{
int val = getClimblingWaysWithCache(n-1,map)+getClimblingWaysWithCache(n-2,map);
map.put(n,val);
return val;
}
}
这种算法大大减少时间复杂度,其时间复杂发度和空间复杂度都为O(n)
到这里为止我们并未结束 我们要开始转为一下思维我们不用自顶向下的方法转化为自底向上的方法,如图所示:
在台阶大于3以后 每一个台阶的走法数之和前两个台阶数有关所有我们在可以优化一种新的方法并不不需要记住每一个子集的解,只需要记住前面两个方法的解就好,因此我们引入了第三种方法
方法三、动态规划解法
public int getClimblingWays3(int n ){
if ( n<1 ) return 0;
if (n == 1)return 1;
if (n == 2)return 2;
int a = 1;
int b = 2;
int temp =0;
for(int i = 3;i <= n ;i++){
temp = b + a;
a = b;
b = temp;
}
return temp;
}
程序从i=3开始到i=n结束 即只有F(n)n>=3的时候才开始进入循环。好了到此为止最简单的动态规划问题就全部梳理好了。
动态规划-爬楼梯问题java实现的更多相关文章
- climbing stairs(爬楼梯)(动态规划)
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- 【leetcode70】【动态规划】 爬楼梯
(1 pass 一维动态规划) 爬楼梯(easy) 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数 ...
- Climbing Stairs爬楼梯——动态规划
题目描写叙述: 初阶:有n层的台阶,一開始你站在第0层,每次能够爬两层或者一层. 请问爬到第n层有多少种不同的方法? 进阶:假设每次能够爬两层.和倒退一层,同一个位置不能反复走,请问爬到第n层有多少种 ...
- LeetCode初级算法--动态规划01:爬楼梯
LeetCode初级算法--动态规划01:爬楼梯 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...
- Leetcode题目70.爬楼梯(动态规划+递归-简单)
题目描述: 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2 输出: 2 ...
- Leetcode之动态规划(DP)专题-746. 使用最小花费爬楼梯(Min Cost Climbing Stairs)
Leetcode之动态规划(DP)专题-746. 使用最小花费爬楼梯(Min Cost Climbing Stairs) 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 cost ...
- Java实现 LeetCode 746 使用最小花费爬楼梯(递推)
746. 使用最小花费爬楼梯 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 costi. 每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶 ...
- Java实现 LeetCode70 爬楼梯
70. 爬楼梯 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2 输出: ...
- lintcode: 爬楼梯
题目: 爬楼梯 假设你正在爬楼梯,需要n步你才能到达顶部.但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部? 样例 比如n=3,中不同的方法 返回 3 解题: 动态规划题目,同时还是有顺序 ...
随机推荐
- Bootstrap入门(1)简介
作者:赵盼盼 出处:https://www.cnblogs.com/zhaopanpan/ Bootstrap是Twitter开源的基于HTML.CSS.JavaScript的前端框架. 它是为实现快 ...
- python-调用自己写的函数
在同一个目录下的话,直接在代码里添加即可,下面的例子. 同一个目录下有以下: aaa.py ccc.py ddd.py 想在ddd.py里用aaa.py里的函数,就在ddd.py里面开关位置添加 ...
- 【转载】C/C++内存管理详解
转自:http://chenqx.github.io/2014/09/25/Cpp-Memory-Management/ 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中 ...
- redis解决方案之三种集群模式的概念与部署
上篇文章为大家总结了redis命令并讲述了持久化,今天我们来看一下redis的三种集群模式:主从复制,哨兵集群,Cluster集群 本篇文章先介绍redis-cluster集群模式,然后再依次介绍它的 ...
- springboot 整合GuavaCache缓存
Guava Cache是一种本地缓存机制,之所以叫本地缓存,是因为它不会把缓存数据放到外部文件或者其他服务器上,而是存放到了应用内存中. Guava Cache的优点是:简单.强大.轻量级. Guav ...
- ISR吞吐性能问题
ISR大致可以分几类: Cisco 860.880.890 ISR1800 (fixed).1800 (modular).2800.3800 Series ISR1900.2900.3800.3900 ...
- ASA映射80端口到公网
1.测试拓扑: 2.测试目的:Web Server:192.168.1.100/24 GW:192.168.1.254Internet:200.1.1.2/24 映射的地址:200.1.1.3 3.配 ...
- 转载:ADTS header
转自:http://blog.csdn.net/tx3344/article/details/7414543 1.ADTS是个啥 ADTS全称是(Audio Data Transport Stream ...
- 【Python】第一个程序---Helloworld!
对于大多数程序语言,第一个入门编程代码便是"Hello World!",以下代码为使用Python输出"Hello World!": #!/usr/bin/py ...
- PHP array_chunk() 妙用
定义和用法 array_chunk()函数把一个数组分割为新的数组块. array_chunk(array,size,preserve_keys); 参数 描述 array 必需.规定要使用的数组. ...