LeetCode0070-爬楼梯

递归经典题目-爬楼梯

https://leetcode-cn.com/problems/climbing-stairs/

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

 

递归的三个条件:

1.一个问题的解可以分解为几个子问题的解

2.这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样

3.存在递归终止条件。

 

写递归代码的关键就是找到如何将大问题分解为小问题的规律,并且基于此写 出递推公式,然后再推敲终止条件,最后将递推公式和终止条件翻译成代码。

编写递归代码的关键是,只要遇到递归,我们就把它抽象成一个递推公式,不用想一 层层的调用关系,不要试图用人脑去分解递归的每个步骤。

编写递归代码的关键就是不要把自己绕进去,正确姿势 是写出递推公式,找出终止条件,然后再翻译成递归代码。

 

摘自:数据结构与算法之美  王争

一、递归实现

最简单的实现方式:

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

 

上述过程,重复计算部分消耗了最多的时间资源,导致执行时会直接超时,

下面做了重复计算的剔除,用hashmap记录每一层的结果值,如果曾经计算过,就不去重新计算,

class Solution {

//注意静态变量的使用方式
static HashMap<Integer,Integer> temp = new HashMap<Integer,Integer>();

//需要把静态变量的初始化内容放到static代码块中,否则系统会报错
static { temp.put(1,1); temp.put(2,2);} public int climbStairs(int n) { int res=0; if(temp.containsKey(n)) return temp.get(n); else{ res= climbStairs(n-1)+climbStairs(n-2); temp.put(n,res); } return res; } }

 

二、递归的非递归实现->动态规划

基本上所有的递归代码都可以改为迭代循环的非递归写法,因为递归本身就是接住栈来实现的。其实非递归实现模拟的是手动入栈出栈的操作,本质不变。

 public int climbStairs(int n) {
        int p=0,q=0,r=1;
        for(int i=1;i<=n;i++){
            p=q;
            q=r;
            r=p+q;
        }
        return r;
    }

 

动态规划与递归:

一句话,去除了重复计算的递归就是动态规划。

posted on 2021-07-09 15:47  cStream  阅读(46)  评论(0)    收藏  举报