LeetCode 之 Climbing Stairs

来源:互联网 发布:rmvb转mov mac 编辑:程序博客网 时间:2024/05/16 11:59
原题:

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

第一次看到这个题,我擦,又一个动态规划,好,先直接来个最简单的给服务器来点压力,没想到,我猜对了,超时了。。。。不过思想应该可行,如下:设一个函数,求n个台阶已经走了前k个时的所有可能number,那么在这种情况下只能有两种选择,走一步或者走两步,而且这个时候可选的可能性就是走一步后剩余情况和走2步剩余情况的。。。。

虽然超时,but,只要加个备忘就哦了么(自顶向下的方法)。。。。

超时代码:

class Solution {public:    int climbStairs(int n) {        // IMPORTANT: Please reset any member data you declared, as        // the same Solution instance will be reused for each test case.        return number (0 , n);    }    //共n个台阶,前k个已经决定了策略,总共的爬楼梯可能    int number (int k, int n){        if ( k == n-2 ) return 2;         if ( k == n-1 ) return 1;        else return number( k+1 , n ) + number ( k+2 , n);    }};

正确的思路:加一个备忘录,这是动态规划自顶向下的标准算法之一

由于从上面的代码看到number(k,n)中调用了number(k+1,n),于是定义一个数组record来记录number(k,n),主要有一个需要注意的地方,也是递归最难的部分,就是判定什么时候返回,这个题比较简单,只有两种情况

1 k==n-1时,即离终点只有一个台阶时,只能有一种可能

2 k==n-2时,即离终点有两个台阶时,有两种可能

代码如下:

class Solution {public:            int climbStairs(int n) {        // IMPORTANT: Please reset any member data you declared, as        // the same Solution instance will be reused for each test case.                int record [n];                //先初始化一下        for (int i = 0 ;i < n ; i++){            record[i]= -1;        }        return number (0 , n , record);    }    //共n个台阶,前k个已经决定了策略,总共的爬楼梯可能    int number (int k, int n , int record [] ){        if(record[k] >= 0){            return record[k];        }           int result = 0;        if ( k == n-2 ) {         //return之前保存一下,距离终点只有2个台阶,有2种可能            result =  2;        }        else if ( k == n-1 ){            //return之前保存一下,距离终点只有1个台阶,有一种可能            result = 1;        }         else {            result = number( k+1 , n , record) + number ( k+2 , n ,record) ;        }                record[k] = result;        return result;           }};

动态规划也可以利用自底向上。。。。